From 0f4c8544d8b822bd0d97da75b47b1244d147bef3 Mon Sep 17 00:00:00 2001 From: Doug Szumski Date: Mon, 26 Jan 2026 11:25:34 +0000 Subject: Support multiple Nova Compute Ironic instances Adds support for deploying multiple instances of the Nova Compute Ironic service on the same host. This is useful in large baremetal deployments, where the sharding and/or conductor group feature is used to scale out the service. A further patch to support deploying multiple Ironic conductor instances will follow. Co-Authored-By: Bartosz Bezak Co-Authored-By: Bertrand Lanson Change-Id: Ibbddfd87e831a3775c3ed66c80b18e5070cedc90 Signed-off-by: Doug Szumski --- kolla_ansible/tests/unit/test_nova_filters.py | 86 +++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'kolla_ansible/tests') diff --git a/kolla_ansible/tests/unit/test_nova_filters.py b/kolla_ansible/tests/unit/test_nova_filters.py index e8d5c507a..d436b0ef1 100644 --- a/kolla_ansible/tests/unit/test_nova_filters.py +++ b/kolla_ansible/tests/unit/test_nova_filters.py @@ -73,6 +73,92 @@ class TestFilters(unittest.TestCase): self.assertRaisesRegex(jinja2.TemplateRuntimeError, 'duplicates', self._test_extract_cell, test_data, 'cell0001') + def test_get_expected_ironic_compute_services_multi_compute(self): + example_ironic_compute_conf = { + # We expect the classic config to be ignored + 'classic': ['custom-host-nova-compute'], + # We have a batch of 2 Ironic compute hosts which should + # run a total of 3 Nova compute Ironic instances + 'multi': [ + ['nova-compute-ironic-1', + 'nova-compute-ironic-2', + 'nova-compute-ironic', + 'something'], + ['nova-compute-ironic-3', + 'nova-compute-ironic', + 'something'], + ] + } + multi_conf = [ + {"custom_host": "some_custom_host"}, + {"shard_key": "shard_1", "conductor_group": "location_1"}, + {"shard_key": "shard_2", "conductor_group": "location_1"}, + {"conductor_group": "location_2"}, + {"shard_key": "shard_1"} + ] + actual = filters.get_expected_ironic_compute_services( + example_ironic_compute_conf, multi_conf, 'nova-compute-ironic') + expected = [ + 'some_custom_host-ironic', + 'location_1-shard_1-ironic', + 'location_1-shard_2-ironic', + ] + self.assertListEqual(actual, expected) + + def test_get_expected_ironic_compute_services_no_compute(self): + example_ironic_compute_conf = { + 'classic': [], + 'multi': [] + } + actual = filters.get_expected_ironic_compute_services( + example_ironic_compute_conf, [], 'nova-compute-ironic') + expected = [] + self.assertListEqual(actual, expected) + + def test_get_expected_ironic_compute_services_classic_compute(self): + example_ironic_compute_conf = { + 'classic': ['custom-foo'], + 'multi': [] + } + actual = filters.get_expected_ironic_compute_services( + example_ironic_compute_conf, [], 'nova-compute-ironic') + expected = ['custom-foo-ironic'] + self.assertListEqual(actual, expected) + + def test_get_expected_ironic_compute_services_classic_compute_multi(self): + # NOTE(dougszu): This isn't a recommended configuration + example_ironic_compute_conf = { + 'classic': ['custom-foo', 'ctrl02', 'ctrl03'], + 'multi': [] + } + actual = filters.get_expected_ironic_compute_services( + example_ironic_compute_conf, [], 'nova-compute-ironic') + expected = [ + 'custom-foo-ironic', + 'ctrl02-ironic', + 'ctrl03-ironic', + ] + self.assertListEqual(actual, expected) + + def test_get_expected_ironic_compute_services_bad_config(self): + example_ironic_compute_conf = { + 'classic': [], + 'multi': [ + ['my-custom-group-1', + 'my-custom-group-2', + 'my-custom-group', + 'something'], + ] + } + multi_conf = [ + {"shard_key": "shard_1", "conductor_group": "location_1"}, + ] + with self.assertRaisesRegex(Exception, + 'Unable to look up multi-compute Ironic ' + 'config for my-custom-group-2'): + filters.get_expected_ironic_compute_services( + example_ironic_compute_conf, multi_conf, 'my-custom-group') + def test_namespace_haproxy_for_cell_with_empty_name(self): example_services = { 'nova-novncproxy': { -- cgit v1.2.3