From 00ed8a232bc22f48011e95a0b47750520a5b4d47 Mon Sep 17 00:00:00 2001 From: Kashyap Chamarthy Date: Tue, 26 Jul 2022 16:02:17 +0200 Subject: [PATCH] Add a workaround to skip hypervisor version check on LM When turned on, this will disable the version-checking of hypervisors during live-migration. This can be useful for operators in certain scenarios when upgrading. E.g. if you want to relocate all instances off a compute node due to an emergency hardware issue, and you only have another old compute node ready at the time. Note, though: libvirt will do its own internal compatibility checks, and might still reject live migration if the destination is incompatible. Closes-Bug: #1982853 Change-Id: Iec387dcbc49ddb91ebf5cfd188224eaf6021c0e1 Signed-off-by: Kashyap Chamarthy --- nova/conductor/tasks/live_migrate.py | 5 ++-- nova/conf/workarounds.py | 7 +++++ .../unit/conductor/tasks/test_live_migrate.py | 30 +++++++++++++++++++ ...-version-check-on-lm-a87f2dcb4f8bf0f2.yaml | 13 ++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/skip-hypervisor-version-check-on-lm-a87f2dcb4f8bf0f2.yaml diff --git a/nova/conductor/tasks/live_migrate.py b/nova/conductor/tasks/live_migrate.py index 1acae88b2645..f8819b0dc854 100644 --- a/nova/conductor/tasks/live_migrate.py +++ b/nova/conductor/tasks/live_migrate.py @@ -347,8 +347,9 @@ class LiveMigrationTask(base.TaskBase): source_version = source_info.hypervisor_version destination_version = destination_info.hypervisor_version - if source_version > destination_version: - raise exception.DestinationHypervisorTooOld() + if not CONF.workarounds.skip_hypervisor_version_check_on_lm: + if source_version > destination_version: + raise exception.DestinationHypervisorTooOld() return source_info, destination_info def _call_livem_checks_on_host(self, destination, provider_mapping): diff --git a/nova/conf/workarounds.py b/nova/conf/workarounds.py index 6c52eae8e5d0..2ec53282cdbe 100644 --- a/nova/conf/workarounds.py +++ b/nova/conf/workarounds.py @@ -409,6 +409,13 @@ With the libvirt driver, during live migration, skip comparing guest CPU with the destination host. When using QEMU >= 2.9 and libvirt >= 4.4.0, libvirt will do the correct thing with respect to checking CPU compatibility on the destination host during live migration. +"""), + cfg.BoolOpt( + 'skip_hypervisor_version_check_on_lm', + default=False, + help=""" +When this is enabled, it will skip version-checking of hypervisors +during live migration. """), ] diff --git a/nova/tests/unit/conductor/tasks/test_live_migrate.py b/nova/tests/unit/conductor/tasks/test_live_migrate.py index cb40c076c82d..dd4ee7c3fec1 100644 --- a/nova/tests/unit/conductor/tasks/test_live_migrate.py +++ b/nova/tests/unit/conductor/tasks/test_live_migrate.py @@ -345,6 +345,36 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): mock.call(self.destination)], mock_get_info.call_args_list) + @mock.patch.object(live_migrate.LiveMigrationTask, '_get_compute_info') + def test_skip_hypervisor_version_check_on_lm_raise_ex(self, mock_get_info): + host1 = {'hypervisor_type': 'a', 'hypervisor_version': 7} + host2 = {'hypervisor_type': 'a', 'hypervisor_version': 6} + self.flags(group='workarounds', + skip_hypervisor_version_check_on_lm=False) + mock_get_info.side_effect = [objects.ComputeNode(**host1), + objects.ComputeNode(**host2)] + self.assertRaises(exception.DestinationHypervisorTooOld, + self.task._check_compatible_with_source_hypervisor, + self.destination) + self.assertEqual([mock.call(self.instance_host), + mock.call(self.destination)], + mock_get_info.call_args_list) + + @mock.patch.object(live_migrate.LiveMigrationTask, '_get_compute_info') + def test_skip_hypervisor_version_check_on_lm_do_not_raise_ex( + self, mock_get_info + ): + host1 = {'hypervisor_type': 'a', 'hypervisor_version': 7} + host2 = {'hypervisor_type': 'a', 'hypervisor_version': 6} + self.flags(group='workarounds', + skip_hypervisor_version_check_on_lm=True) + mock_get_info.side_effect = [objects.ComputeNode(**host1), + objects.ComputeNode(**host2)] + self.task._check_compatible_with_source_hypervisor(self.destination) + self.assertEqual([mock.call(self.instance_host), + mock.call(self.destination)], + mock_get_info.call_args_list) + @mock.patch.object(compute_rpcapi.ComputeAPI, 'check_can_live_migrate_destination') def test_check_requested_destination(self, mock_check): diff --git a/releasenotes/notes/skip-hypervisor-version-check-on-lm-a87f2dcb4f8bf0f2.yaml b/releasenotes/notes/skip-hypervisor-version-check-on-lm-a87f2dcb4f8bf0f2.yaml new file mode 100644 index 000000000000..00fe6a24c70b --- /dev/null +++ b/releasenotes/notes/skip-hypervisor-version-check-on-lm-a87f2dcb4f8bf0f2.yaml @@ -0,0 +1,13 @@ +--- +feature: + - | + Adds a workaround that allows one to disable hypervisor + version-check on live migration. This workaround option can be + useful in certain scenarios when upgrading. E.g. if you want to + relocate all instances off a compute node due to an emergency + hardware issue, and you only have another old compute node ready at + the time. + + To enable this, use the config attribute + ``[workarounds]skip_hypervisor_version_check_on_lm=True`` in + ``nova.conf``. The option defaults to ``False``.