commit 4d695dcc621f3b956c0ab06fb8b2c0e4b3a35dfd Author: Wiktor Sleczka Date: Fri Sep 25 09:22:23 2020 +0200 OVS for SRiOV nodes working Change-Id: I8b538ca28fb85ed0459a73497998cc32f6bc5fea (cherry picked from commit b70c9345ca65e93315ed8dc99222b5749c328350) diff --git a/networking_opencontrail/repository/vmi.py b/networking_opencontrail/repository/vmi.py index c8eecb6..b1df889 100644 --- a/networking_opencontrail/repository/vmi.py +++ b/networking_opencontrail/repository/vmi.py @@ -19,7 +19,6 @@ from networking_opencontrail.neutron import neutron_client from networking_opencontrail.repository.utils.client import tf_client from networking_opencontrail.repository.utils.initialize import reconnect from networking_opencontrail.repository.utils import tagger -from networking_opencontrail.repository.utils.utils import request_node from networking_opencontrail.repository.utils.utils import request_project from networking_opencontrail.repository.vpg import PHYSICAL_NETWORK from networking_opencontrail import resources @@ -49,15 +48,14 @@ def create(q_port, q_network): network = tf_client.read_network(uuid=q_network["id"]) vlan_id = q_network.get("provider:segmentation_id") - node = request_node(node_name) - - if resources.utils.is_sriov_node(node): + if utils.is_sriov_port(q_port): physical_network = q_network[PHYSICAL_NETWORK] vpg_name = resources.vpg.make_name(node_name, physical_network) - else: - vpg_name = resources.vpg.make_name(node_name) + return create_from_tf_data( + project, network, node_name, vlan_id, vpg_name) - create_from_tf_data(project, network, node_name, vlan_id, vpg_name) + vpg_name = resources.vpg.make_name(node_name) + return create_from_tf_data(project, network, node_name, vlan_id, vpg_name) @reconnect @@ -95,7 +93,8 @@ def vmi_exists(network_uuid, node_name): @reconnect -def create_from_tf_data(project, network, node_name, vlan_id, vpg_name): +def create_from_tf_data( + project, network, node_name, vlan_id, vpg_name): vmi = resources.vmi.create(project, network, node_name, vlan_id) tf_client.create_vmi(vmi) @@ -105,8 +104,8 @@ def create_from_tf_data(project, network, node_name, vlan_id, vpg_name): def _attach_to_vpg(vmi, vpg_name): vpg_uuid = utils.make_uuid(vpg_name) - vpg = tf_client.read_vpg(uuid=vpg_uuid) + vpg.add_virtual_machine_interface(vmi) tf_client.update_vpg(vpg) diff --git a/networking_opencontrail/repository/vpg.py b/networking_opencontrail/repository/vpg.py index 82ff28b..3466ae7 100644 --- a/networking_opencontrail/repository/vpg.py +++ b/networking_opencontrail/repository/vpg.py @@ -34,7 +34,7 @@ def create(q_port, q_network): resources.vmi.validate(q_port, q_network) node = utils.request_node(q_port['binding:host_id']) - if resources.utils.is_sriov_node(node): + if resources.utils.is_sriov_port(q_port): physical_network = q_network[PHYSICAL_NETWORK] vpg = create_for_physical_network(node, physical_network) @@ -50,7 +50,7 @@ def delete(q_port, q_network): resources.vmi.validate(q_port, q_network) node = utils.request_node(q_port['binding:host_id']) - if resources.utils.is_sriov_node(node): + if resources.utils.is_sriov_port(q_port): physical_network = q_network[PHYSICAL_NETWORK] vpg = _read_from_node_and_network(node, physical_network) else: @@ -106,7 +106,8 @@ def create_for_node(node): vpg = resources.vpg.create(node, fabric) tf_client.create_vpg(vpg) - _add_physical_interfaces(vpg, node) + physical_interfaces = request_physical_interfaces(node) + add_physical_interfaces(vpg, physical_interfaces) tf_client.update_vpg(vpg) return vpg @@ -116,6 +117,14 @@ def create_for_node(node): def create_for_physical_network(node, network_name): """Create a VPG attached to the provided node and physical network.""" vpg = _read_from_node_and_network(node, network_name) + physical_interfaces = request_physical_interfaces(node, network_name) + if not physical_interfaces: + LOG.info( + "No physical interfaces found on {node} for network {network}" + " falling back to per node setup" + .format(node=node.name, network=network_name)) + + return create_for_node(node) if vpg: LOG.info("VPG %s already exists", vpg.display_name) @@ -128,15 +137,19 @@ def create_for_physical_network(node, network_name): vpg = resources.vpg.create(node, fabric, network_name) tf_client.create_vpg(vpg) - _add_physical_interfaces(vpg, node, network_name) + add_physical_interfaces(vpg, physical_interfaces) tf_client.update_vpg(vpg) return vpg -def _add_physical_interfaces(vpg, node, network_name=None): +def request_physical_interfaces(node, network_name=None): physical_interfaces = utils.request_physical_interfaces_from_node( node, network_name) + return physical_interfaces + + +def add_physical_interfaces(vpg, physical_interfaces): for physical_interface in physical_interfaces: vpg.add_physical_interface(ref_obj=physical_interface) diff --git a/networking_opencontrail/resources/utils.py b/networking_opencontrail/resources/utils.py index a7fc5cb..382c7c3 100644 --- a/networking_opencontrail/resources/utils.py +++ b/networking_opencontrail/resources/utils.py @@ -23,9 +23,9 @@ ovs_compute = 'ovs-compute' baremetal = 'baremetal' -def is_sriov_node(node): - """Determine if node uses sriov data ports.""" - return node.node_type == sriov_compute +def is_sriov_port(q_port): + """Show if port is SRiOV based""" + return q_port['binding:vif_type'] == 'hw_veb' def first(iterable, condition=lambda x: True, default=None): diff --git a/networking_opencontrail/resources/vpg.py b/networking_opencontrail/resources/vpg.py index 9d4b18b..a422e84 100644 --- a/networking_opencontrail/resources/vpg.py +++ b/networking_opencontrail/resources/vpg.py @@ -19,6 +19,7 @@ from vnc_api import vnc_api from networking_opencontrail.exceptions import InvalidResource from networking_opencontrail.resources.utils import destandardize_name from networking_opencontrail.resources.utils import first +from networking_opencontrail.resources.utils import is_sriov_port from networking_opencontrail.resources.utils import make_uuid from networking_opencontrail.resources.utils import standardize_name from networking_opencontrail.resources.vmi import validate @@ -110,7 +111,7 @@ def make_names_from_q_data(q_ports, q_networks): node_name = q_port['binding:host_id'] - if q_port['binding:vif_type'] == 'hw_veb': + if is_sriov_port(q_port): network_name = q_network['provider:physical_network'] vpg_name = make_name(node_name, network_name) else: diff --git a/networking_opencontrail/sync/synchronizers.py b/networking_opencontrail/sync/synchronizers.py index 975b8e0..09598a3 100644 --- a/networking_opencontrail/sync/synchronizers.py +++ b/networking_opencontrail/sync/synchronizers.py @@ -195,12 +195,37 @@ class VMISynchronizer(base.ResourceSynchronizer): LOG.error("Couldn't find node %s for VMI %s", node_name, vmi_name) return - if utils.is_sriov_node(node): + vlan_id = q_network.get('provider:segmentation_id') + + # List of ports is satisfactory, as all of them should be run through + # the same interface. + matching_ports = neutron_client.list_ports(self._context, filters={ + "binding:host_id": [node_name], + "network_id": [network_uuid] + }) + if utils.is_sriov_port(matching_ports[0]): physical_network = q_network[repository.vpg.PHYSICAL_NETWORK] vpg_name = resources.vpg.make_name(node_name, physical_network) - else: - vpg_name = resources.vpg.make_name(node_name) + vpg_uuid = utils.make_uuid(vpg_name) + if tf_client.read_vpg(uuid=vpg_uuid): + repository.vmi.create_from_tf_data( + project, + network, + node_name, + vlan_id, + vpg_name) + else: + LOG.error( + "Couldn't find VPG %s for VMI %s with physnet %s." + " Skipping", + vpg_name, + vmi_name, + physical_network + ) + + return + vpg_name = resources.vpg.make_name(node_name) vpg_uuid = utils.make_uuid(vpg_name) if tf_client.read_vpg(uuid=vpg_uuid) is None: LOG.warning(