Align with latest SR-IOV CNI and device plugin images
Currently, StarlingX uses a version of the SR-IOV CNI and device plugin container images that are based on a certain commit reference. This is done to ensure reliable and predicable behaviour until the images can be locked down on a stable release version. It is desirable to move to a later version of these images for a couple of reasons (aside from bug fixes, etc): 1. The SR-IOV CNI image now uses an alpine base, rather than a Redhat base. 2. The SR-IOV device plugin allows a DPDK enabled pod with Mellanox NICs to run unprivileged. This commit makes the necessary changes to handle the change to the SR-IOV device plugin configuration file. An example of the new format is as follows: { "resourceList": [{ "resourceName": "pci_sriov_net_network1", "selectors": { "vendors": ["8086"], "devices": ["154c", "10ed"], "drivers": ["i40evf", "ixgbevf"], "pfNames": ["ens802f0", "ens801f0"] } }] } As such, it can be seen that the vendor and device ids must be read, rather than the old format which just needed the PCI root device address(es). To achieve this, the sysinv agent must read and store any SR-IOV virtual function device ids. The vendor id can be read from the existing pvendor id field of the port with the addition of the -nn flag to the lspci command. Change-Id: Id73eaa1cf8ff39643c113d4787417f3b44b1560f Depends-on: https://review.opendev.org/685498 Partial-Bug: 1835020 Signed-off-by: Steven Webster <steven.webster@windriver.com>
This commit is contained in:
parent
75ab4cfde9
commit
919d1c98fe
|
@ -19,6 +19,7 @@ def _print_port_show(port):
|
|||
'type', 'pciaddr', 'dev_id', 'numa_node',
|
||||
'sriov_totalvfs', 'sriov_numvfs',
|
||||
'sriov_vfs_pci_address', 'sriov_vf_driver',
|
||||
'sriov_vf_pdevice_id',
|
||||
'driver', 'pclass', 'pvendor', 'pdevice',
|
||||
'capabilities',
|
||||
'uuid', 'host_uuid', 'interface_uuid',
|
||||
|
@ -28,6 +29,7 @@ def _print_port_show(port):
|
|||
'type', 'pciaddr', 'dev_id', 'processor',
|
||||
'sriov_totalvfs', 'sriov_numvfs',
|
||||
'sriov_vfs_pci_address', 'sriov_vf_driver',
|
||||
'sriov_vf_pdevice_id',
|
||||
'driver', 'pclass', 'pvendor', 'pdevice',
|
||||
'capabilities',
|
||||
'uuid', 'host_uuid', 'interface_uuid',
|
||||
|
|
|
@ -657,6 +657,7 @@ class AgentManager(service.PeriodicService):
|
|||
'sriov_numvfs': port.sriov_numvfs,
|
||||
'sriov_vfs_pci_address': port.sriov_vfs_pci_address,
|
||||
'sriov_vf_driver': port.sriov_vf_driver,
|
||||
'sriov_vf_pdevice_id': port.sriov_vf_pdevice_id,
|
||||
'driver': port.driver,
|
||||
'mac': port.mac,
|
||||
'mtu': port.mtu,
|
||||
|
|
|
@ -16,6 +16,7 @@ import os
|
|||
import shlex
|
||||
import subprocess
|
||||
|
||||
from oslo_utils._i18n import _
|
||||
from sysinv.common import constants
|
||||
from sysinv.common import utils
|
||||
from sysinv.openstack.common import log as logging
|
||||
|
@ -128,6 +129,7 @@ class Port(object):
|
|||
self.sriov_numvfs = kwargs.get('sriov_numvfs')
|
||||
self.sriov_vfs_pci_address = kwargs.get('sriov_vfs_pci_address')
|
||||
self.sriov_vf_driver = kwargs.get('sriov_vf_driver')
|
||||
self.sriov_vf_pdevice_id = kwargs.get('sriov_vf_pdevice_id')
|
||||
self.driver = kwargs.get('driver')
|
||||
self.dpdksupport = kwargs.get('dpdksupport')
|
||||
|
||||
|
@ -235,6 +237,31 @@ class PCIOperator(object):
|
|||
LOG.debug("sriov_vfs_pci_address: %s" % sriov_vfs_pci_address)
|
||||
return sriov_vfs_pci_address
|
||||
|
||||
def get_pci_sriov_vf_device_id(self, pciaddr, sriov_vfs_pci_address):
|
||||
vf_device_id = None
|
||||
for addr in sriov_vfs_pci_address:
|
||||
fdevice = '/sys/bus/pci/devices/' + addr + '/device'
|
||||
|
||||
try:
|
||||
with open(fdevice, 'r') as f:
|
||||
# Device id is a 16 bit hex value. Strip off the hex
|
||||
# identifier and trailing whitespace
|
||||
vf_device_id = hex(int(f.readline().rstrip(), 16))[2:]
|
||||
if len(vf_device_id) <= 4:
|
||||
# Should never happen
|
||||
raise ValueError(_(
|
||||
"Device Id must be a 16 bit hex value"))
|
||||
LOG.debug("ATTR sriov_vf_device_id: %s " % vf_device_id)
|
||||
except Exception:
|
||||
LOG.debug("ATTR sriov_vf_device_id unknown for: %s " % pciaddr)
|
||||
pass
|
||||
|
||||
# All VFs have the same device id per device.
|
||||
if vf_device_id:
|
||||
break
|
||||
|
||||
return vf_device_id
|
||||
|
||||
def get_pci_sriov_vf_driver_name(self, pciaddr, sriov_vfs_pci_address):
|
||||
vf_driver = None
|
||||
for addr in sriov_vfs_pci_address:
|
||||
|
@ -306,7 +333,7 @@ class PCIOperator(object):
|
|||
|
||||
def inics_get(self):
|
||||
|
||||
p = subprocess.Popen(["lspci", "-Dm"], stdout=subprocess.PIPE)
|
||||
p = subprocess.Popen(["lspci", "-Dmnn"], stdout=subprocess.PIPE)
|
||||
|
||||
pci_inics = []
|
||||
for line in p.stdout:
|
||||
|
@ -470,6 +497,7 @@ class PCIOperator(object):
|
|||
sriov_numvfs = self.get_pci_sriov_numvfs(a)
|
||||
sriov_vfs_pci_address = self.get_pci_sriov_vfs_pci_address(a, sriov_numvfs)
|
||||
sriov_vf_driver = self.get_pci_sriov_vf_driver_name(a, sriov_vfs_pci_address)
|
||||
sriov_vf_pdevice_id = self.get_pci_sriov_vf_device_id(a, sriov_vfs_pci_address)
|
||||
driver = self.get_pci_driver_name(a)
|
||||
|
||||
# Determine DPDK support
|
||||
|
@ -625,6 +653,7 @@ class PCIOperator(object):
|
|||
"sriov_vfs_pci_address":
|
||||
','.join(str(x) for x in sriov_vfs_pci_address),
|
||||
"sriov_vf_driver": sriov_vf_driver,
|
||||
"sriov_vf_pdevice_id": sriov_vf_pdevice_id,
|
||||
"driver": driver,
|
||||
"pci_address": a,
|
||||
"mac": mac,
|
||||
|
|
|
@ -106,6 +106,9 @@ class EthernetPort(base.APIBase):
|
|||
sriov_vf_driver = wtypes.text
|
||||
"The SR-IOV VF driver for this device"
|
||||
|
||||
sriov_vf_pdevice_id = wtypes.text
|
||||
"The SR-IOV VF PCI device id for this device"
|
||||
|
||||
driver = wtypes.text
|
||||
"The kernel driver for this device"
|
||||
|
||||
|
@ -174,6 +177,7 @@ class EthernetPort(base.APIBase):
|
|||
'psvendor', 'psdevice', 'numa_node',
|
||||
'mac', 'sriov_totalvfs', 'sriov_numvfs',
|
||||
'sriov_vfs_pci_address', 'sriov_vf_driver',
|
||||
'sriov_vf_pdevice_id',
|
||||
'driver', 'mtu', 'speed', 'link_mode',
|
||||
'duplex', 'autoneg', 'bootp',
|
||||
'capabilities',
|
||||
|
|
|
@ -3192,7 +3192,77 @@ class HostController(rest.RestController):
|
|||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
@staticmethod
|
||||
def _semantic_check_sriov_interface(host, interface, force_unlock=False):
|
||||
def _check_sriovdp_interface_datanets(iface):
|
||||
"""
|
||||
Perform SR-IOV device plugin semantic checks on a specific interface.
|
||||
"""
|
||||
ihost_uuid = iface.ihost_uuid
|
||||
dbapi = pecan.request.dbapi
|
||||
|
||||
host_labels = dbapi.label_get_by_host(ihost_uuid)
|
||||
if not cutils.has_sriovdp_enabled(host_labels):
|
||||
return
|
||||
|
||||
if (iface.ifclass != constants.INTERFACE_CLASS_PCI_SRIOV and
|
||||
iface.ifclass != constants.INTERFACE_CLASS_PCI_PASSTHROUGH):
|
||||
return
|
||||
|
||||
iface_dn, x = interface_api._datanetworks_get_by_interface(
|
||||
iface.uuid)
|
||||
|
||||
# Collect all datanets and interfaces for the host to ensure
|
||||
# they are compatible with the interface being checked
|
||||
host_ifaces = dbapi.iinterface_get_by_ihost(ihost_uuid)
|
||||
for host_iface in host_ifaces:
|
||||
if host_iface.ifclass != iface.ifclass:
|
||||
# Only interfaces of the same class need to be checked
|
||||
# for compatibility
|
||||
continue
|
||||
if host_iface.uuid == iface.uuid:
|
||||
# Ignore the current interface
|
||||
continue
|
||||
|
||||
host_iface_dn, x = interface_api._datanetworks_get_by_interface(
|
||||
host_iface.uuid)
|
||||
|
||||
shared_dn = [dn for dn in host_iface_dn if dn in iface_dn]
|
||||
if not shared_dn:
|
||||
continue
|
||||
|
||||
# SR-IOV interfaces on the same data network must not have a
|
||||
# mix of vfio / netdevice devices
|
||||
if iface.ifclass == constants.INTERFACE_CLASS_PCI_SRIOV:
|
||||
netdevice_driver = constants.SRIOV_DRIVER_TYPE_NETDEVICE
|
||||
driver1 = iface.sriov_vf_driver or netdevice_driver
|
||||
driver2 = host_iface.sriov_vf_driver or netdevice_driver
|
||||
if driver1 != driver2:
|
||||
msg = (_("VF driver (%s) for interface (%s) conflicts "
|
||||
"with VF driver (%s) for interface (%s) "
|
||||
"on data network(s) (%s). "
|
||||
"Consider choosing another data network" %
|
||||
(driver1, iface.ifname, driver2,
|
||||
host_iface.ifname, shared_dn)))
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
# SR-IOV interfaces on the same data network must not have a
|
||||
# mix of Mellanox / Intel devices
|
||||
iports = dbapi.ethernet_port_get_by_interface(iface.uuid)
|
||||
hports = dbapi.ethernet_port_get_by_interface(host_iface.uuid)
|
||||
hport_drivers = [h['driver'] for h in hports]
|
||||
iport_drivers = [i['driver'] for i in iports]
|
||||
mlx_drivers = constants.MELLANOX_DRIVERS
|
||||
|
||||
if (len(set(hport_drivers) & set(mlx_drivers)) !=
|
||||
len(set(iport_drivers) & set(mlx_drivers))):
|
||||
msg = (_("PF driver(s) (%s) for interface (%s) conflict with "
|
||||
"PF driver(s) (%s) for interface (%s) "
|
||||
"on data network(s) (%s). "
|
||||
"Consider choosing another data network" %
|
||||
(iport_drivers, iface.ifname, hport_drivers,
|
||||
host_iface.ifname, shared_dn)))
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def _semantic_check_sriov_interface(self, host, interface, force_unlock=False):
|
||||
"""
|
||||
Perform semantic checks on an SRIOV interface.
|
||||
"""
|
||||
|
@ -3228,11 +3298,24 @@ class HostController(rest.RestController):
|
|||
for p in ports:
|
||||
if (interface.sriov_vf_driver == constants.SRIOV_DRIVER_TYPE_NETDEVICE and
|
||||
p.sriov_vf_driver is None):
|
||||
msg = (_("Value for SR-IOV VF driver is 'netdevice', but "
|
||||
"corresponding port has an invalid driver"))
|
||||
msg = (_("Value for SR-IOV VF driver is %s, but "
|
||||
"corresponding port has an invalid driver" %
|
||||
constants.SRIOV_DRIVER_TYPE_NETDEVICE))
|
||||
LOG.info(msg)
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
self._check_sriovdp_interface_datanets(interface)
|
||||
|
||||
def _semantic_check_pcipt_interface(self, host, interface, force_unlock=False):
|
||||
"""
|
||||
Perform semantic checks on an PCI-PASSTHROUGH interface.
|
||||
"""
|
||||
if (force_unlock or
|
||||
interface.ifclass != constants.INTERFACE_CLASS_PCI_PASSTHROUGH):
|
||||
return
|
||||
|
||||
self._check_sriovdp_interface_datanets(interface)
|
||||
|
||||
def _semantic_check_unlock_upgrade(self, ihost, force_unlock=False):
|
||||
"""
|
||||
Perform semantic checks related to upgrades prior to unlocking host.
|
||||
|
@ -3367,6 +3450,7 @@ class HostController(rest.RestController):
|
|||
if not iif.ifclass:
|
||||
continue
|
||||
self._semantic_check_sriov_interface(ihost, iif, force_unlock)
|
||||
self._semantic_check_pcipt_interface(ihost, iif, force_unlock)
|
||||
|
||||
@staticmethod
|
||||
def _auto_adjust_memory_for_node(ihost, node):
|
||||
|
|
|
@ -104,6 +104,9 @@ class Port(base.APIBase):
|
|||
sriov_vf_driver = wtypes.text
|
||||
"The SR-IOV VF driver for this device"
|
||||
|
||||
sriov_vf_pdevice_id = wtypes.text
|
||||
"The SR-IOV VF PCI device id for this device"
|
||||
|
||||
driver = wtypes.text
|
||||
"The kernel driver for this device"
|
||||
|
||||
|
@ -154,6 +157,7 @@ class Port(base.APIBase):
|
|||
'psvendor', 'psdevice', 'numa_node',
|
||||
'sriov_totalvfs', 'sriov_numvfs',
|
||||
'sriov_vfs_pci_address', 'sriov_vf_driver',
|
||||
'sriov_vf_pdevice_id',
|
||||
'driver', 'capabilities',
|
||||
'host_uuid', 'interface_uuid',
|
||||
'node_uuid', 'dpdksupport',
|
||||
|
|
|
@ -649,6 +649,7 @@ PCI_NETWORK_TYPES = [NETWORK_TYPE_PCI_PASSTHROUGH,
|
|||
|
||||
SRIOV_DRIVER_TYPE_VFIO = 'vfio'
|
||||
SRIOV_DRIVER_TYPE_NETDEVICE = 'netdevice'
|
||||
SRIOV_DRIVER_VFIO_PCI = 'vfio-pci'
|
||||
SRIOV_DRIVER_TYPES = [SRIOV_DRIVER_TYPE_VFIO,
|
||||
SRIOV_DRIVER_TYPE_NETDEVICE]
|
||||
|
||||
|
@ -1509,3 +1510,10 @@ CEPH_MON_0 = 'ceph-mon-0-ip'
|
|||
CEPH_MON_1 = 'ceph-mon-1-ip'
|
||||
CEPH_MON_2 = 'ceph-mon-2-ip'
|
||||
CEPH_FLOATING_MON = 'ceph-floating-mon-ip'
|
||||
|
||||
# Mellanox interface definitions
|
||||
DRIVER_MLX_CX3 = 'mlx4_core'
|
||||
DRIVER_MLX_CX4 = 'mlx5_core'
|
||||
|
||||
MELLANOX_DRIVERS = [DRIVER_MLX_CX3,
|
||||
DRIVER_MLX_CX4]
|
||||
|
|
|
@ -2023,6 +2023,20 @@ def has_openstack_compute(labels):
|
|||
return False
|
||||
|
||||
|
||||
def has_sriovdp_enabled(labels):
|
||||
"""Returns true if the sriovdp=enabled label is set """
|
||||
if not labels:
|
||||
return False
|
||||
|
||||
for label in labels:
|
||||
if (label.label_key == helm_common.LABEL_SRIOVDP and
|
||||
label.label_value):
|
||||
return helm_common.LABEL_VALUE_ENABLED == label.label_value.lower()
|
||||
|
||||
# We haven't found the sriovdp node key. Return False
|
||||
return False
|
||||
|
||||
|
||||
def get_vswitch_type(dbapi):
|
||||
system = dbapi.isystem_get_one()
|
||||
return system.capabilities.get('vswitch_type', None)
|
||||
|
|
|
@ -1977,6 +1977,8 @@ class ConductorManager(service.PeriodicService):
|
|||
inic['sriov_vfs_pci_address'],
|
||||
'sriov_vf_driver':
|
||||
inic['sriov_vf_driver'],
|
||||
'sriov_vf_pdevice_id':
|
||||
inic['sriov_vf_pdevice_id'],
|
||||
'driver': inic['driver'],
|
||||
'dpdksupport': inic['dpdksupport'],
|
||||
'speed': inic['speed'],
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from sqlalchemy import Column, MetaData, String, Table
|
||||
|
||||
ENGINE = 'InnoDB'
|
||||
CHARSET = 'utf8'
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
ports = Table('ports', meta, autoload=True)
|
||||
ports.create_column(Column('sriov_vf_pdevice_id', String(4)))
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
# Downgrade is unsupported in this release.
|
||||
raise NotImplementedError('SysInv database downgrade is unsupported.')
|
|
@ -455,6 +455,7 @@ class Ports(Base):
|
|||
sriov_totalvfs = Column(Integer)
|
||||
sriov_numvfs = Column(Integer)
|
||||
sriov_vf_driver = Column(String(255))
|
||||
sriov_vf_pdevice_id = Column(String(4))
|
||||
# Each PCI Address is 12 char, 1020 char is enough for 64 devices
|
||||
sriov_vfs_pci_address = Column(String(1020))
|
||||
driver = Column(String(255))
|
||||
|
|
|
@ -98,6 +98,7 @@ LABEL_CONTROLLER = 'openstack-control-plane'
|
|||
LABEL_COMPUTE_LABEL = 'openstack-compute-node'
|
||||
LABEL_OPENVSWITCH = 'openvswitch'
|
||||
LABEL_REMOTE_STORAGE = 'remote-storage'
|
||||
LABEL_SRIOVDP = 'sriovdp'
|
||||
|
||||
LABEL_MONITOR_CONTROLLER = 'elastic-controller'
|
||||
LABEL_MONITOR_MASTER = 'elastic-master'
|
||||
|
|
|
@ -42,6 +42,7 @@ class Port(base.SysinvObject):
|
|||
'sriov_numvfs': utils.int_or_none,
|
||||
'sriov_vfs_pci_address': utils.str_or_none,
|
||||
'sriov_vf_driver': utils.str_or_none,
|
||||
'sriov_vf_pdevice_id': utils.str_or_none,
|
||||
'driver': utils.str_or_none,
|
||||
'capabilities': utils.dict_or_none,
|
||||
}
|
||||
|
|
|
@ -44,12 +44,6 @@ ACTIVE_STANDBY_AE_MODES = ['active_backup', 'active-backup', 'active_standby']
|
|||
BALANCED_AE_MODES = ['balanced', 'balanced-xor']
|
||||
LACP_AE_MODES = ['802.3ad']
|
||||
|
||||
DRIVER_MLX_CX3 = 'mlx4_core'
|
||||
DRIVER_MLX_CX4 = 'mlx5_core'
|
||||
|
||||
MELLANOX_DRIVERS = [DRIVER_MLX_CX3,
|
||||
DRIVER_MLX_CX4]
|
||||
|
||||
LOOPBACK_IFNAME = 'lo'
|
||||
LOOPBACK_METHOD = 'loopback'
|
||||
STATIC_METHOD = 'static'
|
||||
|
@ -424,7 +418,7 @@ def is_a_mellanox_device(context, iface):
|
|||
# devices.
|
||||
return False
|
||||
port = get_interface_port(context, iface)
|
||||
if port['driver'] in MELLANOX_DRIVERS:
|
||||
if port['driver'] in constants.MELLANOX_DRIVERS:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -438,7 +432,7 @@ def is_a_mellanox_cx3_device(context, iface):
|
|||
# devices.
|
||||
return False
|
||||
port = get_interface_port(context, iface)
|
||||
if port['driver'] == DRIVER_MLX_CX3:
|
||||
if port['driver'] == constants.DRIVER_MLX_CX3:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -983,9 +977,9 @@ def get_sriov_config(context, iface):
|
|||
return {}
|
||||
|
||||
if vf_driver:
|
||||
if "vfio" in vf_driver:
|
||||
vf_driver = "vfio-pci"
|
||||
elif "netdevice" in vf_driver:
|
||||
if constants.SRIOV_DRIVER_TYPE_VFIO in vf_driver:
|
||||
vf_driver = constants.SRIOV_DRIVER_VFIO_PCI
|
||||
elif constants.SRIOV_DRIVER_TYPE_NETDEVICE in vf_driver:
|
||||
if port['sriov_vf_driver'] is not None:
|
||||
vf_driver = port['sriov_vf_driver']
|
||||
else:
|
||||
|
@ -1264,7 +1258,7 @@ def build_mlx4_num_vfs_options(context):
|
|||
modprobe conf file in which VF is set and reload the mlx4_core
|
||||
kernel module
|
||||
"""
|
||||
ifaces = find_sriov_interfaces_by_driver(context, DRIVER_MLX_CX3)
|
||||
ifaces = find_sriov_interfaces_by_driver(context, constants.DRIVER_MLX_CX3)
|
||||
if not ifaces:
|
||||
return ""
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
from __future__ import absolute_import
|
||||
import netaddr
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
|
@ -276,6 +277,39 @@ class KubernetesPuppet(base.BasePuppet):
|
|||
interfaces.append(iface)
|
||||
return interfaces
|
||||
|
||||
def _get_pcidp_vendor_id(self, port):
|
||||
vendor = None
|
||||
# The vendor id can be found by inspecting the '[xxxx]' at the
|
||||
# end of the port's pvendor field
|
||||
vendor = re.search(r'\[([0-9a-fA-F]{1,4})\]$', port['pvendor'])
|
||||
if vendor:
|
||||
vendor = vendor.group(1)
|
||||
return vendor
|
||||
|
||||
def _get_pcidp_device_id(self, port, ifclass):
|
||||
device = None
|
||||
if ifclass == constants.INTERFACE_CLASS_PCI_SRIOV:
|
||||
device = port['sriov_vf_pdevice_id']
|
||||
else:
|
||||
# The device id can be found by inspecting the '[xxxx]' at the
|
||||
# end of the port's pdevice field
|
||||
device = re.search(r'\[([0-9a-fA-F]{1,4})\]$', port['pdevice'])
|
||||
if device:
|
||||
device = device.group(1)
|
||||
return device
|
||||
|
||||
def _get_pcidp_driver(self, port, iface, ifclass):
|
||||
if ifclass == constants.INTERFACE_CLASS_PCI_SRIOV:
|
||||
sriov_vf_driver = iface.get('sriov_vf_driver', None)
|
||||
if (sriov_vf_driver and
|
||||
constants.SRIOV_DRIVER_TYPE_VFIO in sriov_vf_driver):
|
||||
driver = constants.SRIOV_DRIVER_VFIO_PCI
|
||||
else:
|
||||
driver = port['sriov_vf_driver']
|
||||
else:
|
||||
driver = port['driver']
|
||||
return driver
|
||||
|
||||
def _get_pcidp_network_resources_by_ifclass(self, ifclass):
|
||||
resources = {}
|
||||
|
||||
|
@ -286,24 +320,54 @@ class KubernetesPuppet(base.BasePuppet):
|
|||
for datanet in datanets:
|
||||
dn_name = datanet['name'].strip()
|
||||
resource = resources.get(dn_name, None)
|
||||
if resource:
|
||||
# Add to the list of pci addreses for this data network
|
||||
resource['rootDevices'].append(port['pciaddr'])
|
||||
else:
|
||||
device_type = iface.get('sriov_vf_driver', None)
|
||||
if not device_type:
|
||||
device_type = constants.SRIOV_DRIVER_TYPE_NETDEVICE
|
||||
|
||||
# PCI addresses don't exist for this data network yet
|
||||
resource = {dn_name: {
|
||||
if not resource:
|
||||
resource = {
|
||||
"resourceName": "{}_net_{}".format(
|
||||
ifclass, dn_name).replace("-", "_"),
|
||||
"deviceType": device_type,
|
||||
"rootDevices": [port['pciaddr']],
|
||||
"sriovMode":
|
||||
ifclass == constants.INTERFACE_CLASS_PCI_SRIOV
|
||||
}}
|
||||
resources.update(resource)
|
||||
"selectors": {
|
||||
"vendors": [],
|
||||
"devices": [],
|
||||
"drivers": [],
|
||||
"pfNames": []
|
||||
}
|
||||
}
|
||||
|
||||
vendor = self._get_pcidp_vendor_id(port)
|
||||
if not vendor:
|
||||
LOG.error("Failed to get vendor id for pci device %s", port['pciaddr'])
|
||||
continue
|
||||
|
||||
device = self._get_pcidp_device_id(port, ifclass)
|
||||
if not device:
|
||||
LOG.error("Failed to get device id for pci device %s", port['pciaddr'])
|
||||
continue
|
||||
|
||||
driver = self._get_pcidp_driver(port, iface, ifclass)
|
||||
if not device:
|
||||
LOG.error("Failed to get driver for pci device %s", port['pciaddr'])
|
||||
continue
|
||||
|
||||
vendor_list = resource['selectors']['vendors']
|
||||
if vendor not in vendor_list:
|
||||
vendor_list.append(vendor)
|
||||
|
||||
device_list = resource['selectors']['devices']
|
||||
if device not in device_list:
|
||||
device_list.append(device)
|
||||
|
||||
driver_list = resource['selectors']['drivers']
|
||||
if driver not in driver_list:
|
||||
driver_list.append(driver)
|
||||
|
||||
pf_name_list = resource['selectors']['pfNames']
|
||||
if port['name'] not in pf_name_list:
|
||||
pf_name_list.append(port['name'])
|
||||
|
||||
if interface.is_a_mellanox_device(self.context, iface):
|
||||
resource['isRdma'] = True
|
||||
|
||||
resources[dn_name] = resource
|
||||
|
||||
return list(resources.values())
|
||||
|
||||
def _get_pcidp_network_resources(self):
|
||||
|
|
|
@ -1110,10 +1110,11 @@ class TestPatch(InterfaceTestCase):
|
|||
self.assertEqual(vf_driver, response.json['sriov_vf_driver'])
|
||||
|
||||
def test_create_sriov_vf_driver_netdevice_valid(self):
|
||||
self._create_sriov_vf_driver_valid('netdevice')
|
||||
self._create_sriov_vf_driver_valid(
|
||||
constants.SRIOV_DRIVER_TYPE_NETDEVICE)
|
||||
|
||||
def test_create_sriov_vf_driver_vfio_valid(self):
|
||||
self._create_sriov_vf_driver_valid('vfio')
|
||||
self._create_sriov_vf_driver_valid(constants.SRIOV_DRIVER_TYPE_VFIO)
|
||||
|
||||
def test_create_sriov_vf_driver_invalid(self):
|
||||
self._create_sriov_vf_driver_valid('bad_driver', expect_errors=True)
|
||||
|
|
|
@ -1912,3 +1912,15 @@ class TestMigrations(BaseMigrationTestCase, WalkVersionsMixin):
|
|||
for col, coltype in ports_col.items():
|
||||
self.assertTrue(isinstance(ports.c[col].type,
|
||||
getattr(sqlalchemy.types, coltype)))
|
||||
|
||||
def _check_094(self, engine, data):
|
||||
# 094_sriov_vf_device.py
|
||||
|
||||
# Assert data types for new columns in table "ports"
|
||||
ports = db_utils.get_table(engine, 'ports')
|
||||
ports_col = {
|
||||
'sriov_vf_pdevice_id': 'String',
|
||||
}
|
||||
for col, coltype in ports_col.items():
|
||||
self.assertTrue(isinstance(ports.c[col].type,
|
||||
getattr(sqlalchemy.types, coltype)))
|
||||
|
|
|
@ -806,6 +806,7 @@ def get_test_port(**kw):
|
|||
'sriov_numvfs': kw.get('sriov_numvfs'),
|
||||
'sriov_vfs_pci_address': kw.get('sriov_vfs_pci_address'),
|
||||
'sriov_vf_driver': kw.get('sriov_vf_driver'),
|
||||
'sriov_vf_pdevice_id': kw.get('sriov_vf_pdevice_id'),
|
||||
'driver': kw.get('driver'),
|
||||
'capabilities': kw.get('capabilities'),
|
||||
'created_at': kw.get('created_at'),
|
||||
|
@ -848,6 +849,7 @@ def get_test_ethernet_port(**kw):
|
|||
'sriov_totalvfs': kw.get('sriov_totalvfs'),
|
||||
'sriov_numvfs': kw.get('sriov_numvfs'),
|
||||
'sriov_vf_driver': kw.get('sriov_vf_driver'),
|
||||
'sriov_vf_pdevice_id': kw.get('sriov_vf_pdevice_id'),
|
||||
'driver': kw.get('driver')
|
||||
}
|
||||
return ethernet_port
|
||||
|
@ -919,7 +921,7 @@ def post_get_test_interface(**kw):
|
|||
'ipv4_pool': kw.get('ipv4_pool'),
|
||||
'ipv6_pool': kw.get('ipv6_pool'),
|
||||
'sriov_numvfs': kw.get('sriov_numvfs', None),
|
||||
'sriov_vf_driver': kw.get('sriov_vf_driver', None),
|
||||
'sriov_vf_driver': kw.get('sriov_vf_driver', None)
|
||||
}
|
||||
return interface
|
||||
|
||||
|
@ -946,7 +948,8 @@ def get_test_interface(**kw):
|
|||
'ipv4_pool': kw.get('ipv4_pool'),
|
||||
'ipv6_pool': kw.get('ipv6_pool'),
|
||||
'sriov_numvfs': kw.get('sriov_numvfs', None),
|
||||
'sriov_vf_driver': kw.get('sriov_vf_driver', None)
|
||||
'sriov_vf_driver': kw.get('sriov_vf_driver', None),
|
||||
'sriov_vf_pdevice_id': kw.get('sriov_vf_pdevice_id', None)
|
||||
}
|
||||
return interface
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ class InterfaceTestCaseMixin(base.PuppetTestCaseMixin):
|
|||
'0000:00:00.' + str(port_id + 1)),
|
||||
'dev_id': kwargs.get('dev_id', 0),
|
||||
'sriov_vf_driver': kwargs.get('sriov_vf_driver', None),
|
||||
'sriov_vf_pdevice_id': kwargs.get('sriov_vf_pdevice_id', None),
|
||||
'sriov_vfs_pci_address': kwargs.get('sriov_vfs_pci_address', '')}
|
||||
db_port = dbutils.create_test_ethernet_port(**port)
|
||||
self.ports.append(db_port)
|
||||
|
@ -791,7 +792,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self.iface['ifclass'] = constants.INTERFACE_CLASS_DATA
|
||||
self.iface['networktype'] = constants.NETWORK_TYPE_DATA
|
||||
self.host['personality'] = constants.CONTROLLER
|
||||
self.port['driver'] = interface.DRIVER_MLX_CX3
|
||||
self.port['driver'] = constants.DRIVER_MLX_CX3
|
||||
self._update_context()
|
||||
needed = interface.needs_interface_config(self.context, self.iface)
|
||||
self.assertFalse(needed)
|
||||
|
@ -800,7 +801,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self.iface['ifclass'] = constants.INTERFACE_CLASS_DATA
|
||||
self.iface['networktype'] = constants.NETWORK_TYPE_DATA
|
||||
self.host['personality'] = constants.CONTROLLER
|
||||
self.port['driver'] = interface.DRIVER_MLX_CX4
|
||||
self.port['driver'] = constants.DRIVER_MLX_CX4
|
||||
self._update_context()
|
||||
needed = interface.needs_interface_config(self.context, self.iface)
|
||||
self.assertFalse(needed)
|
||||
|
@ -818,7 +819,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self.iface['ifclass'] = constants.INTERFACE_CLASS_DATA
|
||||
self.iface['networktype'] = constants.NETWORK_TYPE_DATA
|
||||
self.host['personality'] = constants.WORKER
|
||||
self.port['driver'] = interface.DRIVER_MLX_CX3
|
||||
self.port['driver'] = constants.DRIVER_MLX_CX3
|
||||
self._update_context()
|
||||
needed = interface.needs_interface_config(self.context, self.iface)
|
||||
self.assertTrue(needed)
|
||||
|
@ -827,7 +828,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self.iface['ifclass'] = constants.INTERFACE_CLASS_DATA
|
||||
self.iface['networktype'] = constants.NETWORK_TYPE_DATA
|
||||
self.host['personality'] = constants.WORKER
|
||||
self.port['driver'] = interface.DRIVER_MLX_CX4
|
||||
self.port['driver'] = constants.DRIVER_MLX_CX4
|
||||
self._update_context()
|
||||
needed = interface.needs_interface_config(self.context, self.iface)
|
||||
self.assertTrue(needed)
|
||||
|
@ -873,7 +874,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self.iface['networktype'] = constants.NETWORK_TYPE_DATA
|
||||
self.host['personality'] = constants.CONTROLLER
|
||||
self.host['subfunctions'] = constants.WORKER
|
||||
self.port['driver'] = interface.DRIVER_MLX_CX3
|
||||
self.port['driver'] = constants.DRIVER_MLX_CX3
|
||||
self._update_context()
|
||||
needed = interface.needs_interface_config(self.context, self.iface)
|
||||
self.assertTrue(needed)
|
||||
|
@ -883,7 +884,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self.iface['networktype'] = constants.NETWORK_TYPE_DATA
|
||||
self.host['personality'] = constants.CONTROLLER
|
||||
self.host['subfunctions'] = constants.WORKER
|
||||
self.port['driver'] = interface.DRIVER_MLX_CX4
|
||||
self.port['driver'] = constants.DRIVER_MLX_CX4
|
||||
self._update_context()
|
||||
needed = interface.needs_interface_config(self.context, self.iface)
|
||||
self.assertTrue(needed)
|
||||
|
@ -953,7 +954,8 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
'options': 'metric ' + str(metric)}
|
||||
return config
|
||||
|
||||
def _get_sriov_config(self, ifname='default', vf_driver='vfio',
|
||||
def _get_sriov_config(self, ifname='default',
|
||||
vf_driver=constants.SRIOV_DRIVER_TYPE_VFIO,
|
||||
vf_addrs=[""]):
|
||||
config = {'ifname': ifname,
|
||||
'vf_driver': vf_driver,
|
||||
|
@ -1279,14 +1281,14 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
interface.is_a_mellanox_cx3_device(self.context, self.iface))
|
||||
|
||||
def test_is_a_mellanox_cx3_device_true(self):
|
||||
self.port['driver'] = interface.DRIVER_MLX_CX3
|
||||
self.port['driver'] = constants.DRIVER_MLX_CX3
|
||||
self._update_context()
|
||||
self.assertTrue(
|
||||
interface.is_a_mellanox_cx3_device(self.context, self.iface))
|
||||
|
||||
def test_find_sriov_interfaces_by_driver_none(self):
|
||||
ifaces = interface.find_sriov_interfaces_by_driver(
|
||||
self.context, interface.DRIVER_MLX_CX3)
|
||||
self.context, constants.DRIVER_MLX_CX3)
|
||||
self.assertTrue(not ifaces)
|
||||
|
||||
def test_find_sriov_interfaces_by_driver_one(self):
|
||||
|
@ -1298,7 +1300,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self._update_context()
|
||||
|
||||
ifaces = interface.find_sriov_interfaces_by_driver(
|
||||
self.context, interface.DRIVER_MLX_CX3)
|
||||
self.context, constants.DRIVER_MLX_CX3)
|
||||
|
||||
results = [iface['ifname'] for iface in ifaces]
|
||||
self.assertEqual(sorted(results), sorted(expected))
|
||||
|
@ -1312,7 +1314,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
self._update_context()
|
||||
|
||||
ifaces = interface.find_sriov_interfaces_by_driver(
|
||||
self.context, interface.DRIVER_MLX_CX3)
|
||||
self.context, constants.DRIVER_MLX_CX3)
|
||||
|
||||
results = [iface['ifname'] for iface in ifaces]
|
||||
self.assertEqual(sorted(results), sorted(expected))
|
||||
|
@ -1371,7 +1373,7 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
|
|||
port, iface = self._create_ethernet_test(
|
||||
name, constants.INTERFACE_CLASS_PCI_SRIOV,
|
||||
constants.NETWORK_TYPE_PCI_SRIOV,
|
||||
driver=interface.DRIVER_MLX_CX3, sriov_numvfs=vf_num, **kwargs)
|
||||
driver=constants.DRIVER_MLX_CX3, sriov_numvfs=vf_num, **kwargs)
|
||||
return port, iface
|
||||
|
||||
|
||||
|
@ -1620,11 +1622,11 @@ class InterfaceComputeEthernet(InterfaceHostTestCase):
|
|||
port, iface = (
|
||||
self._create_ethernet_test('mlx4', constants.INTERFACE_CLASS_DATA,
|
||||
constants.NETWORK_TYPE_DATA,
|
||||
driver=interface.DRIVER_MLX_CX3))
|
||||
driver=constants.DRIVER_MLX_CX3))
|
||||
port, iface = (
|
||||
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
||||
constants.NETWORK_TYPE_DATA,
|
||||
driver=interface.DRIVER_MLX_CX4))
|
||||
driver=constants.DRIVER_MLX_CX4))
|
||||
self._create_ethernet_test('none')
|
||||
|
||||
def setUp(self):
|
||||
|
@ -1761,11 +1763,11 @@ class InterfaceCpeEthernet(InterfaceHostTestCase):
|
|||
port, iface = (
|
||||
self._create_ethernet_test('mlx4', constants.INTERFACE_CLASS_DATA,
|
||||
constants.NETWORK_TYPE_DATA,
|
||||
driver=interface.DRIVER_MLX_CX3))
|
||||
driver=constants.DRIVER_MLX_CX3))
|
||||
port, iface = (
|
||||
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
||||
constants.NETWORK_TYPE_DATA,
|
||||
driver=interface.DRIVER_MLX_CX4))
|
||||
driver=constants.DRIVER_MLX_CX4))
|
||||
self._create_ethernet_test('none')
|
||||
|
||||
def setUp(self):
|
||||
|
@ -1901,11 +1903,11 @@ class InterfaceCpeComputeEthernet(InterfaceHostTestCase):
|
|||
port, iface = (
|
||||
self._create_ethernet_test('mlx4', constants.INTERFACE_CLASS_DATA,
|
||||
constants.NETWORK_TYPE_DATA,
|
||||
driver=interface.DRIVER_MLX_CX3))
|
||||
driver=constants.DRIVER_MLX_CX3))
|
||||
port, iface = (
|
||||
self._create_ethernet_test('mlx5', constants.INTERFACE_CLASS_DATA,
|
||||
constants.NETWORK_TYPE_DATA,
|
||||
driver=interface.DRIVER_MLX_CX4))
|
||||
driver=constants.DRIVER_MLX_CX4))
|
||||
self._create_ethernet_test('none')
|
||||
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue