Do not use own function to find migration target
The nova scenarios BootServerAttachCreatedVolumeAndLiveMigrate, BootServerFromVolumeAndLiveMigrate, BootAndLiveMigrateServer are using rally's own function to find a suitable target compute host for live migration. This function does not support all filters that are available and configured in nova. This function only filters computes on AZ level. For example it completely ignores flavor-aggregate mappings (AggregateInstanceExtraSpecsFilter). This leads to wrong target host selection and thus a failing live migration. This patch removes the function _find_host_to_migrate and the argument target_host that was given into the function _live_migrate. This leaves the target host selection completely up to nova, for live migration, which allows to benefit from the whole nova scheduler filters implementation, to find a suitable host. Change-Id: Ide64667a5e482b10b8935e9ebd7655c0004c6a0b Closes-Bug: #1734914
This commit is contained in:
parent
d060985f7e
commit
eabce92cee
@ -717,9 +717,7 @@ class BootAndLiveMigrateServer(utils.NovaScenario):
|
||||
server = self._boot_server(image, flavor, **kwargs)
|
||||
self.sleep_between(min_sleep, max_sleep)
|
||||
|
||||
new_host = self._find_host_to_migrate(server)
|
||||
self._live_migrate(server, new_host,
|
||||
block_migration, disk_over_commit)
|
||||
self._live_migrate(server, block_migration, disk_over_commit)
|
||||
|
||||
self._delete_server(server)
|
||||
|
||||
@ -774,9 +772,7 @@ class BootServerFromVolumeAndLiveMigrate(utils.NovaScenario,
|
||||
**kwargs)
|
||||
self.sleep_between(min_sleep, max_sleep)
|
||||
|
||||
new_host = self._find_host_to_migrate(server)
|
||||
self._live_migrate(server, new_host,
|
||||
block_migration, disk_over_commit)
|
||||
self._live_migrate(server, block_migration, disk_over_commit)
|
||||
|
||||
self._delete_server(server, force=force_delete)
|
||||
|
||||
@ -832,9 +828,7 @@ class BootServerAttachCreatedVolumeAndLiveMigrate(utils.NovaScenario,
|
||||
|
||||
self.sleep_between(min_sleep, max_sleep)
|
||||
|
||||
new_host = self._find_host_to_migrate(server)
|
||||
self._live_migrate(server, new_host,
|
||||
block_migration, disk_over_commit)
|
||||
self._live_migrate(server, block_migration, disk_over_commit)
|
||||
|
||||
self._detach_volume(server, volume)
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import random
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
@ -737,12 +736,11 @@ class NovaScenario(scenario.OpenStackScenario):
|
||||
)
|
||||
|
||||
@atomic.action_timer("nova.live_migrate")
|
||||
def _live_migrate(self, server, target_host, block_migration=False,
|
||||
def _live_migrate(self, server, block_migration=False,
|
||||
disk_over_commit=False, skip_host_check=False):
|
||||
"""Run live migration of the given server.
|
||||
|
||||
:param server: Server object
|
||||
:param target_host: Specifies the target compute node to migrate
|
||||
:param block_migration: Specifies the migration type
|
||||
:param disk_over_commit: Specifies whether to overcommit migrated
|
||||
instance or not
|
||||
@ -751,8 +749,7 @@ class NovaScenario(scenario.OpenStackScenario):
|
||||
"""
|
||||
server_admin = self.admin_clients("nova").servers.get(server.id)
|
||||
host_pre_migrate = getattr(server_admin, "OS-EXT-SRV-ATTR:host")
|
||||
server_admin.live_migrate(target_host,
|
||||
block_migration=block_migration,
|
||||
server_admin.live_migrate(block_migration=block_migration,
|
||||
disk_over_commit=disk_over_commit)
|
||||
utils.wait_for_status(
|
||||
server,
|
||||
@ -769,30 +766,6 @@ class NovaScenario(scenario.OpenStackScenario):
|
||||
"Live Migration failed: Migration complete "
|
||||
"but instance did not change host: %s" % host_pre_migrate)
|
||||
|
||||
@atomic.action_timer("nova.find_host_to_migrate")
|
||||
def _find_host_to_migrate(self, server):
|
||||
"""Find a compute node for live migration.
|
||||
|
||||
:param server: Server object
|
||||
"""
|
||||
server_admin = self.admin_clients("nova").servers.get(server.id)
|
||||
host = getattr(server_admin, "OS-EXT-SRV-ATTR:host")
|
||||
az_name = getattr(server_admin, "OS-EXT-AZ:availability_zone")
|
||||
az = None
|
||||
for a in self.admin_clients("nova").availability_zones.list():
|
||||
if az_name == a.zoneName:
|
||||
az = a
|
||||
break
|
||||
try:
|
||||
new_host = random.choice(
|
||||
[key for key, value in az.hosts.items()
|
||||
if key != host and
|
||||
value.get("nova-compute", {}).get("available", False)])
|
||||
return new_host
|
||||
except IndexError:
|
||||
raise exceptions.RallyException(
|
||||
"Live Migration failed: No valid host found to migrate")
|
||||
|
||||
@atomic.action_timer("nova.migrate")
|
||||
def _migrate(self, server, skip_host_check=False):
|
||||
"""Run migration of the given server.
|
||||
|
@ -705,8 +705,6 @@ class NovaServersTestCase(test.ScenarioTestCase):
|
||||
scenario.generate_random_name = mock.MagicMock(return_value="name")
|
||||
scenario._boot_server = mock.MagicMock(return_value=fake_server)
|
||||
scenario.sleep_between = mock.MagicMock()
|
||||
scenario._find_host_to_migrate = mock.MagicMock(
|
||||
return_value="host_name")
|
||||
scenario._live_migrate = mock.MagicMock()
|
||||
scenario._delete_server = mock.MagicMock()
|
||||
|
||||
@ -717,10 +715,7 @@ class NovaServersTestCase(test.ScenarioTestCase):
|
||||
|
||||
scenario.sleep_between.assert_called_once_with(10, 20)
|
||||
|
||||
scenario._find_host_to_migrate.assert_called_once_with(fake_server)
|
||||
|
||||
scenario._live_migrate.assert_called_once_with(fake_server,
|
||||
"host_name",
|
||||
False, False)
|
||||
scenario._delete_server.assert_called_once_with(fake_server)
|
||||
|
||||
@ -734,8 +729,6 @@ class NovaServersTestCase(test.ScenarioTestCase):
|
||||
scenario.generate_random_name = mock.MagicMock(return_value="name")
|
||||
scenario._boot_server = mock.MagicMock(return_value=fake_server)
|
||||
scenario.sleep_between = mock.MagicMock()
|
||||
scenario._find_host_to_migrate = mock.MagicMock(
|
||||
return_value="host_name")
|
||||
scenario._live_migrate = mock.MagicMock()
|
||||
scenario._delete_server = mock.MagicMock()
|
||||
|
||||
@ -757,10 +750,7 @@ class NovaServersTestCase(test.ScenarioTestCase):
|
||||
|
||||
scenario.sleep_between.assert_called_once_with(10, 20)
|
||||
|
||||
scenario._find_host_to_migrate.assert_called_once_with(fake_server)
|
||||
|
||||
scenario._live_migrate.assert_called_once_with(fake_server,
|
||||
"host_name",
|
||||
False, False)
|
||||
scenario._delete_server.assert_called_once_with(fake_server,
|
||||
force=False)
|
||||
@ -784,8 +774,6 @@ class NovaServersTestCase(test.ScenarioTestCase):
|
||||
|
||||
scenario.sleep_between = mock.MagicMock()
|
||||
|
||||
scenario._find_host_to_migrate = mock.MagicMock(
|
||||
return_value="host_name")
|
||||
scenario._live_migrate = mock.MagicMock()
|
||||
|
||||
scenario._boot_server = mock.MagicMock(return_value=fake_server)
|
||||
@ -806,7 +794,6 @@ class NovaServersTestCase(test.ScenarioTestCase):
|
||||
fake_volume)
|
||||
scenario.sleep_between.assert_called_once_with(10, 20)
|
||||
scenario._live_migrate.assert_called_once_with(fake_server,
|
||||
"host_name",
|
||||
False, False)
|
||||
|
||||
cinder.delete_volume.assert_called_once_with(fake_volume)
|
||||
|
@ -649,11 +649,9 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
|
||||
"nova.detach_volume")
|
||||
|
||||
def test__live_migrate_server(self):
|
||||
fake_host = mock.MagicMock()
|
||||
self.admin_clients("nova").servers.get(return_value=self.server)
|
||||
nova_scenario = utils.NovaScenario(context=self.context)
|
||||
nova_scenario._live_migrate(self.server,
|
||||
fake_host,
|
||||
block_migration=False,
|
||||
disk_over_commit=False,
|
||||
skip_host_check=True)
|
||||
@ -669,31 +667,6 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
|
||||
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||
"nova.live_migrate")
|
||||
|
||||
def test__find_host_to_migrate(self):
|
||||
fake_server = self.server
|
||||
fake_host = {"nova-compute": {"available": True}}
|
||||
fake_host_compute_off = {"nova-compute": {"available": False}}
|
||||
fake_host_no_compute = {"nova-conductor": {"available": True}}
|
||||
self.admin_clients("nova").servers.get.return_value = fake_server
|
||||
self.admin_clients("nova").availability_zones.list.return_value = [
|
||||
mock.MagicMock(zoneName="a",
|
||||
hosts={"a1": fake_host, "a2": fake_host,
|
||||
"a3": fake_host}),
|
||||
mock.MagicMock(zoneName="b",
|
||||
hosts={"b1": fake_host, "b2": fake_host,
|
||||
"b3": fake_host, "b4": fake_host_compute_off,
|
||||
"b5": fake_host_no_compute}),
|
||||
mock.MagicMock(zoneName="c",
|
||||
hosts={"c1": fake_host,
|
||||
"c2": fake_host, "c3": fake_host})
|
||||
]
|
||||
setattr(fake_server, "OS-EXT-SRV-ATTR:host", "b2")
|
||||
setattr(fake_server, "OS-EXT-AZ:availability_zone", "b")
|
||||
nova_scenario = utils.NovaScenario(context=self.context)
|
||||
|
||||
self.assertIn(
|
||||
nova_scenario._find_host_to_migrate(fake_server), ["b1", "b3"])
|
||||
|
||||
def test__migrate_server(self):
|
||||
fake_server = self.server
|
||||
setattr(fake_server, "OS-EXT-SRV-ATTR:host", "a1")
|
||||
|
Loading…
x
Reference in New Issue
Block a user