Merge "Deprecate options to enable/disable plugin tests"
diff --git a/neutron_tempest_plugin/api/admin/test_tag.py b/neutron_tempest_plugin/api/admin/test_tag.py
index eae7977..31b2b96 100644
--- a/neutron_tempest_plugin/api/admin/test_tag.py
+++ b/neutron_tempest_plugin/api/admin/test_tag.py
@@ -26,53 +26,55 @@
         super(TagTestJSON, cls).resource_setup()
         cls.res_id = cls._create_resource()
 
-    def _get_and_compare_tags(self, tags):
-        res_body = self.client.get_tags(self.resource, self.res_id)
+    def _get_and_compare_tags(self, tags, client):
+        res_body = client.get_tags(self.resource, self.res_id)
         self.assertCountEqual(tags, res_body['tags'])
 
-    def _test_tag_operations(self):
+    def _test_tag_operations(self, client=None):
+        client = client or self.client
         # create and get tags
         tags = ['red', 'blue']
-        res_body = self.client.update_tags(self.resource, self.res_id, tags)
+        res_body = client.update_tags(self.resource, self.res_id, tags)
         self.assertCountEqual(tags, res_body['tags'])
-        self._get_and_compare_tags(tags)
+        self._get_and_compare_tags(tags, client)
 
         # add a tag
-        self.client.update_tag(self.resource, self.res_id, 'green')
-        self._get_and_compare_tags(['red', 'blue', 'green'])
+        client.update_tag(self.resource, self.res_id, 'green')
+        self._get_and_compare_tags(['red', 'blue', 'green'], client)
 
         # update tag exist
-        self.client.update_tag(self.resource, self.res_id, 'red')
-        self._get_and_compare_tags(['red', 'blue', 'green'])
+        client.update_tag(self.resource, self.res_id, 'red')
+        self._get_and_compare_tags(['red', 'blue', 'green'], client)
 
         # add a tag with a dot
-        self.client.update_tag(self.resource, self.res_id, 'black.or.white')
-        self._get_and_compare_tags(['red', 'blue', 'green', 'black.or.white'])
+        client.update_tag(self.resource, self.res_id, 'black.or.white')
+        self._get_and_compare_tags(['red', 'blue', 'green', 'black.or.white'],
+                                   client)
 
         # replace tags
         tags = ['red', 'yellow', 'purple']
-        res_body = self.client.update_tags(self.resource, self.res_id, tags)
+        res_body = client.update_tags(self.resource, self.res_id, tags)
         self.assertCountEqual(tags, res_body['tags'])
-        self._get_and_compare_tags(tags)
+        self._get_and_compare_tags(tags, client)
 
         # get tag
-        self.client.get_tag(self.resource, self.res_id, 'red')
+        client.get_tag(self.resource, self.res_id, 'red')
 
         # get tag not exist
-        self.assertRaises(lib_exc.NotFound, self.client.get_tag,
+        self.assertRaises(lib_exc.NotFound, client.get_tag,
                           self.resource, self.res_id, 'green')
 
         # delete tag
-        self.client.delete_tag(self.resource, self.res_id, 'red')
-        self._get_and_compare_tags(['yellow', 'purple'])
+        client.delete_tag(self.resource, self.res_id, 'red')
+        self._get_and_compare_tags(['yellow', 'purple'], client)
 
         # delete tag not exist
-        self.assertRaises(lib_exc.NotFound, self.client.delete_tag,
+        self.assertRaises(lib_exc.NotFound, client.delete_tag,
                           self.resource, self.res_id, 'green')
 
         # delete tags
-        self.client.delete_tags(self.resource, self.res_id)
-        self._get_and_compare_tags([])
+        client.delete_tags(self.resource, self.res_id)
+        self._get_and_compare_tags([], client)
 
 
 class TagNetworkTestJSON(TagTestJSON):
@@ -198,7 +200,7 @@
     @decorators.idempotent_id('e9bac15e-c8bc-4317-8295-4bf1d8d522b8')
     @utils.requires_ext(extension="standard-attr-tag", service="network")
     def test_qos_policy_tags(self):
-        self._test_tag_operations()
+        self._test_tag_operations(client=self.admin_client)
 
 
 class TagTrunkTestJSON(TagTestJSON):
@@ -225,16 +227,20 @@
     @classmethod
     def resource_setup(cls):
         super(TagFilterTestJSON, cls).resource_setup()
+        try:
+            client = cls.tag_client
+        except AttributeError:
+            client = cls.client
 
         cls.res_ids = []
         for i in range(5):
             cls.res_ids.append(cls._create_resource())
 
-        cls.client.update_tags(cls.resource, cls.res_ids[0], ['red'])
-        cls.client.update_tags(cls.resource, cls.res_ids[1], ['red', 'blue'])
-        cls.client.update_tags(cls.resource, cls.res_ids[2],
-                               ['red', 'blue', 'green'])
-        cls.client.update_tags(cls.resource, cls.res_ids[3], ['green'])
+        client.update_tags(cls.resource, cls.res_ids[0], ['red'])
+        client.update_tags(cls.resource, cls.res_ids[1], ['red', 'blue'])
+        client.update_tags(cls.resource, cls.res_ids[2],
+                           ['red', 'blue', 'green'])
+        client.update_tags(cls.resource, cls.res_ids[3], ['green'])
         # 5th resource: no tags
 
     @classmethod
@@ -441,6 +447,11 @@
         res = self.client.list_qos_policies(**filters)
         return res[self.resource]
 
+    @classmethod
+    def resource_setup(cls):
+        cls.tag_client = cls.admin_client
+        super().resource_setup()
+
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('c2f9a6ae-2529-4cb9-a44b-b16f8ba27832')
     @utils.requires_ext(extension="standard-attr-tag", service="network")
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index e17cf5e..4bcc6d2 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -595,15 +595,11 @@
             # Generate subnet CIDRs starting from configured values
             ip_version = ip_version or cls._ip_version
             if ip_version == const.IP_VERSION_4:
-                mask_bits = mask_bits or config.safe_get_config_value(
-                    'network', 'project_network_mask_bits')
-                cidr = netaddr.IPNetwork(config.safe_get_config_value(
-                    'network', 'project_network_cidr'))
+                mask_bits = mask_bits or CONF.network.project_network_mask_bits
+                cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
             elif ip_version == const.IP_VERSION_6:
-                mask_bits = config.safe_get_config_value(
-                    'network', 'project_network_v6_mask_bits')
-                cidr = netaddr.IPNetwork(config.safe_get_config_value(
-                    'network', 'project_network_v6_cidr'))
+                mask_bits = CONF.network.project_network_v6_mask_bits
+                cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
             else:
                 raise ValueError('Invalid IP version: {!r}'.format(ip_version))
 
diff --git a/neutron_tempest_plugin/api/test_routers.py b/neutron_tempest_plugin/api/test_routers.py
index 7758b1a..1430b81 100644
--- a/neutron_tempest_plugin/api/test_routers.py
+++ b/neutron_tempest_plugin/api/test_routers.py
@@ -38,9 +38,9 @@
     def resource_setup(cls):
         super(RoutersTest, cls).resource_setup()
         cls.tenant_cidr = (
-            config.safe_get_config_value('network', 'project_network_cidr')
+            CONF.network.project_network_cidr
             if cls._ip_version == 4 else
-            config.safe_get_config_value('network', 'project_network_v6_cidr'))
+            CONF.network.project_network_v6_cidr)
 
     @decorators.idempotent_id('c72c1c0c-2193-4aca-eeee-b1442640eeee')
     @tutils.requires_ext(extension="standard-attr-description",
diff --git a/neutron_tempest_plugin/config.py b/neutron_tempest_plugin/config.py
index ba5a5fc..7880eff 100644
--- a/neutron_tempest_plugin/config.py
+++ b/neutron_tempest_plugin/config.py
@@ -248,6 +248,21 @@
 CONF.register_group(taas_group)
 CONF.register_opts(TaasGroup, group="taas")
 
+
+DynamicRoutingGroup = [
+    cfg.StrOpt('base_image',
+               default='quay.io/nf-core/ubuntu:20.04',
+               help=('Base image used to build the image for connectivity '
+                     'check')),
+]
+
+dynamic_routing_group = cfg.OptGroup(
+    name="dynamic_routing",
+    title=("Neutron-Dynamic-Routing Service Options"))
+CONF.register_group(dynamic_routing_group)
+CONF.register_opts(DynamicRoutingGroup, group="dynamic_routing")
+
+
 # DNS Integration with an External Service
 DnsFeatureGroup = [
     cfg.IntOpt(
@@ -259,19 +274,3 @@
     name='designate_feature_enabled', title='Enabled Designate Features')
 CONF.register_group(dns_feature_group)
 CONF.register_opts(DnsFeatureGroup, group="designate_feature_enabled")
-
-config_opts_translator = {
-    'project_network_cidr': 'tenant_network_cidr',
-    'project_network_v6_cidr': 'tenant_network_v6_cidr',
-    'project_network_mask_bits': 'tenant_network_mask_bits',
-    'project_network_v6_mask_bits': 'tenant_network_v6_mask_bits'}
-
-
-def safe_get_config_value(group, name):
-    """Safely get Oslo config opts from Tempest, using old and new names."""
-    conf_group = getattr(CONF, group)
-
-    try:
-        return getattr(conf_group, name)
-    except cfg.NoSuchOptError:
-        return getattr(conf_group, config_opts_translator[name])
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py
index 25b99d6..3f799bb 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/base.py
@@ -40,7 +40,6 @@
 CHECKTIME_INFO = 60
 CHECKTIME_INT = 1
 BRIDGE_TYPE = ctn_base.BRIDGE_TYPE_DOCKER
-BASE_NDR_IMAGE = 'quay.io/nf-core/ubuntu:20.04'
 
 
 def _setup_client_args(auth_provider):
@@ -66,6 +65,7 @@
 
 
 class BgpSpeakerScenarioTestJSONBase(base.BaseAdminNetworkTest):
+    baseimage = CONF.dynamic_routing.base_image
 
     def setUp(self):
         self.addCleanup(self.net_resource_cleanup)
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/base.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/base.py
index cf1a58e..3719dd6 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/base.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/base.py
@@ -84,7 +84,7 @@
                                        router_id=cls.L_AS.router_id)
         cls.dr.set_addr_info(bridge='br-docker-basic', ipv4=cls.public_gw)
         # quagga container
-        cls.dockerimg = ctn_base.DockerImage(baseimage=base.BASE_NDR_IMAGE)
+        cls.dockerimg = ctn_base.DockerImage(baseimage=cls.baseimage)
         cls.q_img = cls.dockerimg.create_quagga(check_exist=True)
         cls.images.append(cls.q_img)
         for i in range(cls.RAS_MAX):
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_4byte_asn.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_4byte_asn.py
index 7ac17d0..1421734 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_4byte_asn.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/basic/test_4byte_asn.py
@@ -91,7 +91,7 @@
                                        router_id=cls.L_AS.router_id)
         cls.dr.set_addr_info(bridge='br-docker-4byte-asn', ipv4=cls.public_gw)
         # quagga container
-        cls.dockerimg = ctn_base.DockerImage(baseimage=base.BASE_NDR_IMAGE)
+        cls.dockerimg = ctn_base.DockerImage(baseimage=cls.baseimage)
         cls.q_img = cls.dockerimg.create_quagga(check_exist=True)
         cls.images.append(cls.q_img)
         for i in range(cls.RAS_MAX):
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv4/test_ipv4.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv4/test_ipv4.py
index ead3a84..57c9018 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv4/test_ipv4.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv4/test_ipv4.py
@@ -91,7 +91,7 @@
                                        router_id=cls.L_AS.router_id)
         cls.dr.set_addr_info(bridge='br-docker-ipv4', ipv4=cls.public_gw)
         # quagga container
-        cls.dockerimg = ctn_base.DockerImage(baseimage=base.BASE_NDR_IMAGE)
+        cls.dockerimg = ctn_base.DockerImage(baseimage=cls.baseimage)
         cls.q_img = cls.dockerimg.create_quagga(check_exist=True)
         cls.images.append(cls.q_img)
         for i in range(cls.RAS_MAX):
diff --git a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv6/test_ipv6.py b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv6/test_ipv6.py
index 29ac079..9bd4c8d 100644
--- a/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv6/test_ipv6.py
+++ b/neutron_tempest_plugin/neutron_dynamic_routing/scenario/ipv6/test_ipv6.py
@@ -91,7 +91,7 @@
                                        router_id=cls.L_AS.router_id)
         cls.dr.set_addr_info(bridge='br-docker-ipv6', ipv6=cls.public_gw)
         # quagga container
-        cls.dockerimg = ctn_base.DockerImage(baseimage=base.BASE_NDR_IMAGE)
+        cls.dockerimg = ctn_base.DockerImage(baseimage=cls.baseimage)
         cls.q_img = cls.dockerimg.create_quagga(check_exist=True)
         cls.images.append(cls.q_img)
         for i in range(cls.RAS_MAX):
diff --git a/releasenotes/notes/dynamic-routing-base-image-12e76a6d85411a6d.yaml b/releasenotes/notes/dynamic-routing-base-image-12e76a6d85411a6d.yaml
new file mode 100644
index 0000000..303e095
--- /dev/null
+++ b/releasenotes/notes/dynamic-routing-base-image-12e76a6d85411a6d.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    The new ``[dynamic_routing] base_image`` option has been added. This option
+    allows customizing the reference of the base container image used for
+    connectivity check in dynamic routing plugin tests.
diff --git a/roles/docker-setup/tasks/main.yml b/roles/docker-setup/tasks/main.yml
index 19d8bfb..1b0e2d7 100644
--- a/roles/docker-setup/tasks/main.yml
+++ b/roles/docker-setup/tasks/main.yml
@@ -4,6 +4,14 @@
     name: docker.io
     state: present
 
+- name: Install docker-buildx (only for Ubuntu and Debian)
+  become: yes
+  package:
+    name: docker-buildx
+    state: present
+  when:
+    - (ansible_facts['distribution'] | lower) in ['ubuntu', 'debian']
+
 - name: Copy 52_docker_for_tempest to /etc/sudoers.d
   copy:
     src: 52_docker_for_tempest
diff --git a/zuul.d/2023_1_jobs.yaml b/zuul.d/2023_1_jobs.yaml
index f038076..706a5d6 100644
--- a/zuul.d/2023_1_jobs.yaml
+++ b/zuul.d/2023_1_jobs.yaml
@@ -1,6 +1,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-2023-1
     parent: neutron-tempest-plugin-openvswitch
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.1
     vars:
       network_api_extensions_openvswitch:
@@ -105,6 +106,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-iptables_hybrid-2023-1
     parent: neutron-tempest-plugin-openvswitch-iptables_hybrid
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -143,6 +145,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-enforce-scope-new-defaults-2023-1
     parent: neutron-tempest-plugin-openvswitch-2023-1
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.1
     vars:
       devstack_localrc:
@@ -160,6 +163,7 @@
 - job:
     name: neutron-tempest-plugin-linuxbridge-2023-1
     parent: neutron-tempest-plugin-linuxbridge
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -201,6 +205,7 @@
 - job:
     name: neutron-tempest-plugin-ovn-2023-1
     parent: neutron-tempest-plugin-ovn
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.1
     vars:
       network_api_extensions_ovn:
@@ -229,6 +234,7 @@
 - job:
     name: neutron-tempest-plugin-dvr-multinode-scenario-2023-1
     parent: neutron-tempest-plugin-dvr-multinode-scenario
+    nodeset: openstack-two-node-jammy
     override-checkout: stable/2023.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -242,6 +248,7 @@
 - job:
     name: neutron-tempest-plugin-designate-scenario-2023-1
     parent: neutron-tempest-plugin-designate-scenario
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -251,6 +258,7 @@
 - job:
     name: neutron-tempest-plugin-sfc-2023-1
     parent: neutron-tempest-plugin-sfc
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.1
     vars:
       devstack_localrc:
@@ -259,6 +267,7 @@
 - job:
     name: neutron-tempest-plugin-bgpvpn-bagpipe-2023-1
     parent: neutron-tempest-plugin-bgpvpn-bagpipe
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.1
     vars:
       devstack_localrc:
@@ -267,11 +276,16 @@
 - job:
     name: neutron-tempest-plugin-dynamic-routing-2023-1
     parent: neutron-tempest-plugin-dynamic-routing
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.1
+    vars:
+      devstack_localrc:
+        NEUTRON_DEPLOY_MOD_WSGI: false
 
 - job:
     name: neutron-tempest-plugin-fwaas-2023-1
     parent: neutron-tempest-plugin-fwaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.1
     vars:
       devstack_localrc:
@@ -280,6 +294,7 @@
 - job:
     name: neutron-tempest-plugin-vpnaas-2023-1
     parent: neutron-tempest-plugin-vpnaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.1
     vars:
       devstack_localrc:
@@ -288,6 +303,7 @@
 - job:
     name: neutron-tempest-plugin-tap-as-a-service-2023-1
     parent: neutron-tempest-plugin-tap-as-a-service
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.1
     vars:
       devstack_localrc:
diff --git a/zuul.d/2023_2_jobs.yaml b/zuul.d/2023_2_jobs.yaml
index 63a63fa..92eac85 100644
--- a/zuul.d/2023_2_jobs.yaml
+++ b/zuul.d/2023_2_jobs.yaml
@@ -1,6 +1,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-2023-2
     parent: neutron-tempest-plugin-openvswitch
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.2
     vars:
       network_api_extensions_openvswitch: &api_extensions_openvswitch
@@ -105,6 +106,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-iptables_hybrid-2023-2
     parent: neutron-tempest-plugin-openvswitch-iptables_hybrid
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -138,6 +140,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-enforce-scope-new-defaults-2023-2
     parent: neutron-tempest-plugin-openvswitch-2023-2
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.2
     vars:
       devstack_localrc:
@@ -155,6 +158,7 @@
 - job:
     name: neutron-tempest-plugin-linuxbridge-2023-2
     parent: neutron-tempest-plugin-linuxbridge
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -196,6 +200,7 @@
 - job:
     name: neutron-tempest-plugin-ovn-2023-2
     parent: neutron-tempest-plugin-ovn
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.2
     vars:
       network_api_extensions_ovn:
@@ -224,6 +229,7 @@
 - job:
     name: neutron-tempest-plugin-dvr-multinode-scenario-2023-2
     parent: neutron-tempest-plugin-dvr-multinode-scenario
+    nodeset: openstack-two-node-jammy
     override-checkout: stable/2023.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -237,6 +243,7 @@
 - job:
     name: neutron-tempest-plugin-designate-scenario-2023-2
     parent: neutron-tempest-plugin-designate-scenario
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2023.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -246,6 +253,7 @@
 - job:
     name: neutron-tempest-plugin-sfc-2023-2
     parent: neutron-tempest-plugin-sfc
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.2
     vars:
       devstack_localrc:
@@ -254,6 +262,7 @@
 - job:
     name: neutron-tempest-plugin-bgpvpn-bagpipe-2023-2
     parent: neutron-tempest-plugin-bgpvpn-bagpipe
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.2
     vars:
       devstack_localrc:
@@ -262,11 +271,16 @@
 - job:
     name: neutron-tempest-plugin-dynamic-routing-2023-2
     parent: neutron-tempest-plugin-dynamic-routing
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.2
+    vars:
+      devstack_localrc:
+        NEUTRON_DEPLOY_MOD_WSGI: false
 
 - job:
     name: neutron-tempest-plugin-fwaas-2023-2
     parent: neutron-tempest-plugin-fwaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.2
     vars:
       devstack_localrc:
@@ -275,6 +289,7 @@
 - job:
     name: neutron-tempest-plugin-vpnaas-2023-2
     parent: neutron-tempest-plugin-vpnaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.2
     vars:
       devstack_localrc:
@@ -283,6 +298,7 @@
 - job:
     name: neutron-tempest-plugin-tap-as-a-service-2023-2
     parent: neutron-tempest-plugin-tap-as-a-service
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2023.2
     vars:
       devstack_localrc:
diff --git a/zuul.d/2024_1_jobs.yaml b/zuul.d/2024_1_jobs.yaml
index c426be6..469fb67 100644
--- a/zuul.d/2024_1_jobs.yaml
+++ b/zuul.d/2024_1_jobs.yaml
@@ -1,6 +1,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-2024-1
     parent: neutron-tempest-plugin-openvswitch
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.1
     vars:
       network_api_extensions_openvswitch: &api_extensions_openvswitch
@@ -107,6 +108,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-iptables_hybrid-2024-1
     parent: neutron-tempest-plugin-openvswitch-iptables_hybrid
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -140,6 +142,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-enforce-scope-new-defaults-2024-1
     parent: neutron-tempest-plugin-openvswitch-2024-1
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.1
     vars:
       devstack_localrc:
@@ -157,6 +160,7 @@
 - job:
     name: neutron-tempest-plugin-linuxbridge-2024-1
     parent: neutron-tempest-plugin-linuxbridge
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -198,6 +202,7 @@
 - job:
     name: neutron-tempest-plugin-ovn-2024-1
     parent: neutron-tempest-plugin-ovn
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.1
     vars:
       network_api_extensions_ovn:
@@ -223,6 +228,7 @@
 - job:
     name: neutron-tempest-plugin-dvr-multinode-scenario-2024-1
     parent: neutron-tempest-plugin-dvr-multinode-scenario
+    nodeset: openstack-two-node-jammy
     override-checkout: stable/2024.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -236,6 +242,7 @@
 - job:
     name: neutron-tempest-plugin-designate-scenario-2024-1
     parent: neutron-tempest-plugin-designate-scenario
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.1
     vars:
       network_api_extensions_common: *api_extensions
@@ -245,6 +252,7 @@
 - job:
     name: neutron-tempest-plugin-sfc-2024-1
     parent: neutron-tempest-plugin-sfc
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.1
     vars:
       devstack_localrc:
@@ -253,6 +261,7 @@
 - job:
     name: neutron-tempest-plugin-bgpvpn-bagpipe-2024-1
     parent: neutron-tempest-plugin-bgpvpn-bagpipe
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.1
     vars:
       devstack_localrc:
@@ -261,11 +270,16 @@
 - job:
     name: neutron-tempest-plugin-dynamic-routing-2024-1
     parent: neutron-tempest-plugin-dynamic-routing
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.1
+    vars:
+      devstack_localrc:
+        NEUTRON_DEPLOY_MOD_WSGI: false
 
 - job:
     name: neutron-tempest-plugin-fwaas-2024-1
     parent: neutron-tempest-plugin-fwaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.1
     vars:
       devstack_localrc:
@@ -274,6 +288,7 @@
 - job:
     name: neutron-tempest-plugin-vpnaas-2024-1
     parent: neutron-tempest-plugin-vpnaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.1
     vars:
       devstack_localrc:
@@ -282,6 +297,7 @@
 - job:
     name: neutron-tempest-plugin-tap-as-a-service-2024-1
     parent: neutron-tempest-plugin-tap-as-a-service
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.1
     vars:
       devstack_localrc:
diff --git a/zuul.d/2024_2_jobs.yaml b/zuul.d/2024_2_jobs.yaml
index bb77ca2..2002142 100644
--- a/zuul.d/2024_2_jobs.yaml
+++ b/zuul.d/2024_2_jobs.yaml
@@ -1,6 +1,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-2024-2
     parent: neutron-tempest-plugin-openvswitch
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.2
     vars:
       network_api_extensions_openvswitch: &api_extensions_openvswitch
@@ -107,6 +108,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-iptables_hybrid-2024-2
     parent: neutron-tempest-plugin-openvswitch-iptables_hybrid
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -139,6 +141,7 @@
 - job:
     name: neutron-tempest-plugin-openvswitch-enforce-scope-new-defaults-2024-1
     parent: neutron-tempest-plugin-openvswitch-2024-1
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.1
     vars:
       devstack_localrc:
@@ -156,6 +159,7 @@
 - job:
     name: neutron-tempest-plugin-linuxbridge-2024-2
     parent: neutron-tempest-plugin-linuxbridge
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -197,6 +201,7 @@
 - job:
     name: neutron-tempest-plugin-ovn-2024-2
     parent: neutron-tempest-plugin-ovn
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.2
     vars:
       network_api_extensions_ovn:
@@ -226,6 +231,7 @@
 - job:
     name: neutron-tempest-plugin-dvr-multinode-scenario-2024-2
     parent: neutron-tempest-plugin-dvr-multinode-scenario
+    nodeset: openstack-two-node-jammy
     override-checkout: stable/2024.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -238,6 +244,7 @@
 - job:
     name: neutron-tempest-plugin-designate-scenario-2024-2
     parent: neutron-tempest-plugin-designate-scenario
+    nodeset: neutron-nested-virt-ubuntu-jammy
     override-checkout: stable/2024.2
     vars:
       network_api_extensions_common: *api_extensions
@@ -247,29 +254,35 @@
 - job:
     name: neutron-tempest-plugin-sfc-2024-2
     parent: neutron-tempest-plugin-sfc
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.2
 
 - job:
     name: neutron-tempest-plugin-bgpvpn-bagpipe-2024-2
     parent: neutron-tempest-plugin-bgpvpn-bagpipe
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.2
 
 - job:
     name: neutron-tempest-plugin-dynamic-routing-2024-2
     parent: neutron-tempest-plugin-dynamic-routing
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.2
 
 - job:
     name: neutron-tempest-plugin-fwaas-2024-2
     parent: neutron-tempest-plugin-fwaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.2
 
 - job:
     name: neutron-tempest-plugin-vpnaas-2024-2
     parent: neutron-tempest-plugin-vpnaas
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.2
 
 - job:
     name: neutron-tempest-plugin-tap-as-a-service-2024-2
     parent: neutron-tempest-plugin-tap-as-a-service
+    nodeset: openstack-single-node-jammy
     override-checkout: stable/2024.2
diff --git a/zuul.d/base-nested-switch.yaml b/zuul.d/base-nested-switch.yaml
index f8fa799..fa5217c 100644
--- a/zuul.d/base-nested-switch.yaml
+++ b/zuul.d/base-nested-switch.yaml
@@ -18,16 +18,26 @@
         nodes:
           - controller
 
-# Base nested switch job for 2023.1 and later
+- nodeset:
+    name: neutron-nested-virt-ubuntu-noble
+    nodes:
+      - name: controller
+        label: nested-virt-ubuntu-noble
+    groups:
+      - name: tempest
+        nodes:
+          - controller
+
+# Base nested switch job for 2025.1 and later
 - job:
     name: neutron-tempest-plugin-base-nested-switch
     parent: neutron-tempest-plugin-base
     abstract: true
     branches:
-      regex: ^(unmaintained|stable/(victoria|wallaby|xena|yoga|zed)).*$
+      regex: ^(unmaintained|stable/(victoria|wallaby|xena|yoga|zed|2023|2024)).*$
       negate: true
     # Comment nodeset and vars to switch back to non nested nodes
-    nodeset: neutron-nested-virt-ubuntu-jammy
+    nodeset: neutron-nested-virt-ubuntu-noble
     vars: &nested_virt_vars
       devstack_localrc:
         LIBVIRT_TYPE: kvm
@@ -39,6 +49,16 @@
         DEFAULT_IMAGE_NAME: cirros-0.5.3-x86_64-disk
         DEFAULT_IMAGE_FILE_NAME: cirros-0.5.3-x86_64-disk.img
 
+# Base nested switch job for 2023.1 till 2024.2
+- job:
+    name: neutron-tempest-plugin-base-nested-switch
+    parent: neutron-tempest-plugin-base
+    abstract: true
+    branches: ^(unmaintained|stable)/(2023|2024).*$
+    # Comment nodeset and vars to switch back to non nested nodes
+    nodeset: neutron-nested-virt-ubuntu-jammy
+    vars: *nested_virt_vars
+
 # Base nested switch job for yoga and zed
 - job:
     name: neutron-tempest-plugin-base-nested-switch
diff --git a/zuul.d/master_jobs.yaml b/zuul.d/master_jobs.yaml
index 9f07d79..a7a3e2e 100644
--- a/zuul.d/master_jobs.yaml
+++ b/zuul.d/master_jobs.yaml
@@ -27,9 +27,9 @@
         NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_tempest) | join(',') }}"
         PHYSICAL_NETWORK: public
         IMAGE_URLS: https://cloud-images.ubuntu.com/minimal/releases/focal/release/ubuntu-20.04-minimal-cloudimg-amd64.img
-        CIRROS_VERSION: 0.6.2
-        DEFAULT_IMAGE_NAME: cirros-0.6.2-x86_64-uec
-        DEFAULT_IMAGE_FILE_NAME: cirros-0.6.2-x86_64-uec.tar.gz
+        CIRROS_VERSION: 0.6.3
+        DEFAULT_IMAGE_NAME: cirros-0.6.3-x86_64-uec
+        DEFAULT_IMAGE_FILE_NAME: cirros-0.6.3-x86_64-uec.tar.gz
         ADVANCED_IMAGE_NAME: ubuntu-20.04-minimal-cloudimg-amd64
         ADVANCED_INSTANCE_TYPE: ntp_image_256M
         ADVANCED_INSTANCE_USER: ubuntu
@@ -37,7 +37,7 @@
         BUILD_TIMEOUT: 784
         # TODO(lucasagomes): Re-enable MOD_WSGI after
         # https://bugs.launchpad.net/neutron/+bug/1912359 is implemented
-        NEUTRON_DEPLOY_MOD_WSGI: false
+        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_plugins:
         neutron: https://opendev.org/openstack/neutron.git
         neutron-tempest-plugin: https://opendev.org/openstack/neutron-tempest-plugin.git
@@ -261,7 +261,6 @@
         Q_ML2_TENANT_NETWORK_TYPE: vxlan
         Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
         NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_openvswitch) | join(',') }}"
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_local_conf:
         post-config:
           $NEUTRON_CONF:
@@ -377,7 +376,6 @@
         Q_ML2_TENANT_NETWORK_TYPE: vxlan
         Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
         NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_openvswitch) | join(',') }}"
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_local_conf:
         post-config:
           $NEUTRON_CONF:
@@ -460,7 +458,6 @@
     vars:
       devstack_localrc:
         NEUTRON_ENFORCE_SCOPE: false
-        NEUTRON_DEPLOY_MOD_WSGI: true
 
 - job:
     name: neutron-tempest-plugin-openvswitch-distributed-dhcp
@@ -645,7 +642,6 @@
         OVN_DBS_LOG_LEVEL: dbg
         ENABLE_TLS: True
         OVN_IGMP_SNOOPING_ENABLE: True
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_services:
         br-ex-tcpdump: true
         br-int-flows: true
@@ -784,22 +780,6 @@
       devstack_localrc:
         NEUTRON_DEPLOY_MOD_WSGI: true
 
-- job:  # To be tested temporarily in the periodic queue
-    name: neutron-tempest-plugin-api-ovs-eventlet
-    parent: neutron-tempest-plugin-openvswitch
-    voting: false
-    vars:
-      devstack_localrc:
-        NEUTRON_DEPLOY_MOD_WSGI: false
-
-- job:  # To be tested temporarily in the periodic queue
-    name: neutron-tempest-plugin-api-ovn-eventlet
-    parent: neutron-tempest-plugin-ovn
-    voting: false
-    vars:
-      devstack_localrc:
-        NEUTRON_DEPLOY_MOD_WSGI: false
-
 - job:
     name: neutron-tempest-plugin-dvr-multinode-scenario
     parent: tempest-multinode-full
@@ -829,9 +809,9 @@
         USE_PYTHON3: true
         NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_dvr) | join(',') }}"
         PHYSICAL_NETWORK: default
-        CIRROS_VERSION: 0.6.2
-        DEFAULT_IMAGE_NAME: cirros-0.6.2-x86_64-uec
-        DEFAULT_IMAGE_FILE_NAME: cirros-0.6.2-x86_64-uec.tar.gz
+        CIRROS_VERSION: 0.6.3
+        DEFAULT_IMAGE_NAME: cirros-0.6.3-x86_64-uec
+        DEFAULT_IMAGE_FILE_NAME: cirros-0.6.3-x86_64-uec.tar.gz
         IMAGE_URLS: https://cloud-images.ubuntu.com/minimal/releases/focal/release/ubuntu-20.04-minimal-cloudimg-amd64.img
         ADVANCED_IMAGE_NAME: ubuntu-20.04-minimal-cloudimg-amd64
         ADVANCED_INSTANCE_TYPE: ntp_image_256M
@@ -1053,7 +1033,6 @@
         # empty
         ADVANCED_IMAGE_NAME: ""
         NETWORK_API_EXTENSIONS: "{{ network_api_extensions_common | join(',') }}"
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_plugins:
         designate: https://opendev.org/openstack/designate.git
       devstack_services:
@@ -1174,7 +1153,6 @@
         Q_ML2_TENANT_NETWORK_TYPE: vxlan
         Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
         NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_sfc) | join(',') }}"
-        NEUTRON_DEPLOY_MOD_WSGI: true
       # TODO(bcafarel): tests still fail from time to time in parallel
       # https://bugs.launchpad.net/neutron/+bug/1851500
       # https://bugs.launchpad.net/networking-sfc/+bug/1660366
@@ -1256,7 +1234,6 @@
         BAGPIPE_DATAPLANE_DRIVER_IPVPN: "ovs"
         BAGPIPE_BGP_PEERS: "-"
         NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_bgpvpn) | join(',') }}"
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_plugins:
         networking-bgpvpn: https://git.openstack.org/openstack/networking-bgpvpn
         networking-bagpipe: https://git.openstack.org/openstack/networking-bagpipe
@@ -1390,7 +1367,6 @@
         Q_AGENT: openvswitch
         Q_ML2_TENANT_NETWORK_TYPE: vxlan
         Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_services:
         # Disable OVN services
         br-ex-tcpdump: false
@@ -1470,7 +1446,6 @@
         Q_AGENT: openvswitch
         Q_ML2_TENANT_NETWORK_TYPE: vxlan
         Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_services:
         # Disable OVN services
         br-ex-tcpdump: false
@@ -1625,7 +1600,6 @@
         Q_AGENT: openvswitch
         Q_ML2_TENANT_NETWORK_TYPE: vxlan,vlan
         Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
-        NEUTRON_DEPLOY_MOD_WSGI: true
       devstack_local_conf:
         post-config:
           /$NEUTRON_CORE_PLUGIN_CONF:
@@ -1721,3 +1695,13 @@
       - ^zuul.d/xena_jobs.yaml
       - ^zuul.d/yoga_jobs.yaml
       - ^zuul.d/zed_jobs.yaml
+
+- job:
+    name: neutron-tempest-plugin-openvswitch-ubuntu-jammy
+    parent: neutron-tempest-plugin-openvswitch
+    nodeset: neutron-nested-virt-ubuntu-jammy
+
+- job:
+    name: neutron-tempest-plugin-ovn-ubuntu-jammy
+    parent: neutron-tempest-plugin-ovn
+    nodeset: neutron-nested-virt-ubuntu-jammy
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index 5feac4e..ee75bf4 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -9,6 +9,8 @@
             # TODO(slaweq) make job voting again once bug
             # https://bugs.launchpad.net/designate/+bug/2072627 will be fixed
             voting: false
+        - neutron-tempest-plugin-openvswitch-ubuntu-jammy
+        - neutron-tempest-plugin-ovn-ubuntu-jammy
     gate:
       jobs:
         - neutron-tempest-plugin-openvswitch
@@ -22,8 +24,6 @@
         - neutron-tempest-plugin-dvr-multinode-scenario
         - neutron-tempest-plugin-openvswitch-distributed-dhcp
         - neutron-tempest-plugin-openvswitch-iptables_hybrid-distributed-dhcp
-        - neutron-tempest-plugin-api-ovs-eventlet
-        - neutron-tempest-plugin-api-ovn-eventlet
         - neutron-tempest-plugin-ovn-enforce-scope-old-defaults
     periodic:
       jobs:
diff --git a/zuul.d/victoria_jobs.yaml b/zuul.d/victoria_jobs.yaml
index 817e759..e38ffe7 100644
--- a/zuul.d/victoria_jobs.yaml
+++ b/zuul.d/victoria_jobs.yaml
@@ -317,6 +317,8 @@
     required-projects: *required-projects-victoria
     vars:
       network_api_extensions_common: *api_extensions
+      devstack_localrc:
+        NEUTRON_DEPLOY_MOD_WSGI: false
 
 - job:
     name: neutron-tempest-plugin-vpnaas-victoria
diff --git a/zuul.d/wallaby_jobs.yaml b/zuul.d/wallaby_jobs.yaml
index 56ed2cf..740f916 100644
--- a/zuul.d/wallaby_jobs.yaml
+++ b/zuul.d/wallaby_jobs.yaml
@@ -248,6 +248,8 @@
     required-projects: *required-projects-wallaby
     vars:
       network_api_extensions_common: *api_extensions
+      devstack_localrc:
+        NEUTRON_DEPLOY_MOD_WSGI: false
 
 - job:
     name: neutron-tempest-plugin-vpnaas-wallaby
diff --git a/zuul.d/zed_jobs.yaml b/zuul.d/zed_jobs.yaml
index 70ab40a..4f6a833 100644
--- a/zuul.d/zed_jobs.yaml
+++ b/zuul.d/zed_jobs.yaml
@@ -266,6 +266,7 @@
         Q_AGENT: openvswitch
         Q_ML2_TENANT_NETWORK_TYPE: vxlan
         Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
+        NEUTRON_DEPLOY_MOD_WSGI: false
       devstack_services:
         # Disable OVN services
         br-ex-tcpdump: false