os-vif 3.1.1__py3-none-any.whl → 3.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of os-vif might be problematic. Click here for more details.
- os_vif/tests/functional/internal/command/ip/test_impl_pyroute2.py +7 -0
- {os_vif-3.1.1.dist-info → os_vif-3.2.0.dist-info}/METADATA +1 -1
- {os_vif-3.1.1.dist-info → os_vif-3.2.0.dist-info}/RECORD +16 -16
- os_vif-3.2.0.dist-info/pbr.json +1 -0
- vif_plug_ovs/ovs.py +63 -5
- vif_plug_ovs/ovsdb/impl_idl.py +2 -1
- vif_plug_ovs/ovsdb/ovsdb_lib.py +51 -2
- vif_plug_ovs/tests/functional/base.py +16 -0
- vif_plug_ovs/tests/functional/ovsdb/test_ovsdb_lib.py +168 -14
- vif_plug_ovs/tests/functional/test_plugin.py +85 -0
- vif_plug_ovs/tests/unit/test_plugin.py +17 -6
- os_vif-3.1.1.dist-info/pbr.json +0 -1
- {os_vif-3.1.1.dist-info → os_vif-3.2.0.dist-info}/AUTHORS +0 -0
- {os_vif-3.1.1.dist-info → os_vif-3.2.0.dist-info}/LICENSE +0 -0
- {os_vif-3.1.1.dist-info → os_vif-3.2.0.dist-info}/WHEEL +0 -0
- {os_vif-3.1.1.dist-info → os_vif-3.2.0.dist-info}/entry_points.txt +0 -0
- {os_vif-3.1.1.dist-info → os_vif-3.2.0.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import os
|
|
14
14
|
import re
|
|
15
|
+
import time
|
|
15
16
|
|
|
16
17
|
from oslo_concurrency import processutils
|
|
17
18
|
from oslo_utils import excutils
|
|
@@ -39,6 +40,12 @@ class ShellIpCommands(object):
|
|
|
39
40
|
'peer', 'name', peer)
|
|
40
41
|
elif 'dummy' == dev_type:
|
|
41
42
|
_execute_command('ip', 'link', 'add', device, 'type', dev_type)
|
|
43
|
+
# ensure that the device exists to prevent racing
|
|
44
|
+
# with other ip commands
|
|
45
|
+
for _ in range(10):
|
|
46
|
+
if self.exist_device(device):
|
|
47
|
+
return
|
|
48
|
+
time.sleep(0.1)
|
|
42
49
|
|
|
43
50
|
def del_device(self, device):
|
|
44
51
|
if self.exist_device(device):
|
|
@@ -30,7 +30,7 @@ os_vif/tests/functional/privsep.py,sha256=c7dqBiO4d-hxgCq-DgbP2A7HB6fdhZK4X0ADYU
|
|
|
30
30
|
os_vif/tests/functional/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
31
|
os_vif/tests/functional/internal/command/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
32
|
os_vif/tests/functional/internal/command/ip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
-
os_vif/tests/functional/internal/command/ip/test_impl_pyroute2.py,sha256=
|
|
33
|
+
os_vif/tests/functional/internal/command/ip/test_impl_pyroute2.py,sha256=J1NsdZAK_OY6dvKlb6HstJAhDvKUOEMzox8sAZGe-mo,9982
|
|
34
34
|
os_vif/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
35
|
os_vif/tests/unit/base.py,sha256=sEjrOSy3yW16WwOorv164ZuUyvKh2TY0gMoVf6lg3kA,795
|
|
36
36
|
os_vif/tests/unit/test_base.py,sha256=iqgweFRWprY98mkGL3HIbV9D8DuX_tUPH8uRiDflwDc,3137
|
|
@@ -65,29 +65,29 @@ vif_plug_ovs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
65
65
|
vif_plug_ovs/constants.py,sha256=P1ngaAA2MioPrSr58JtiDA8rxkl3thttgOvabEyZGIM,944
|
|
66
66
|
vif_plug_ovs/exception.py,sha256=ZiECZVvjCFTVXhuii3uhJn4lZvozKRxziedZB3R9JNo,1328
|
|
67
67
|
vif_plug_ovs/linux_net.py,sha256=nr2dNOECVZtiHSIQHFb5iRVyh7cfLPiIm4VEg3frgDE,14289
|
|
68
|
-
vif_plug_ovs/ovs.py,sha256=
|
|
68
|
+
vif_plug_ovs/ovs.py,sha256=gUpOqhGqmWRfcDWFfctGwP3nJqNKmQqij7HRGNBSdaY,23740
|
|
69
69
|
vif_plug_ovs/privsep.py,sha256=nPQUkYgjbSjaHMuu40fZArRnf8RBiR73l4YpDF1K1yQ,1100
|
|
70
70
|
vif_plug_ovs/ovsdb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
71
|
vif_plug_ovs/ovsdb/api.py,sha256=_jHR8xokDAPI8sw3IEWuT3hObJuskqVzeVMDaWRbIq0,1293
|
|
72
|
-
vif_plug_ovs/ovsdb/impl_idl.py,sha256=
|
|
72
|
+
vif_plug_ovs/ovsdb/impl_idl.py,sha256=DR1aHN8riBpZyNePwpvT9PRYbf9vLk4lRJ9VHRVq_to,3028
|
|
73
73
|
vif_plug_ovs/ovsdb/impl_vsctl.py,sha256=MSf8JMrMqrwt5vH8KTsThjdnsttJEYJikIcJ12CTz8c,14437
|
|
74
|
-
vif_plug_ovs/ovsdb/ovsdb_lib.py,sha256=
|
|
74
|
+
vif_plug_ovs/ovsdb/ovsdb_lib.py,sha256=UfVJG8PtIp2ps51JXp3El9rUgtfR12Mp5dna6_i-20M,10599
|
|
75
75
|
vif_plug_ovs/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
76
|
vif_plug_ovs/tests/functional/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
|
-
vif_plug_ovs/tests/functional/base.py,sha256=
|
|
78
|
-
vif_plug_ovs/tests/functional/test_plugin.py,sha256=
|
|
77
|
+
vif_plug_ovs/tests/functional/base.py,sha256=9EDYKUqsoqVgrYmljb6fZvGmIruL2zNJdIHlEZ9kzu8,1872
|
|
78
|
+
vif_plug_ovs/tests/functional/test_plugin.py,sha256=40gbf5bvxgauHf3U3oT9xeIOcZ3r8-fFRyHOrhWbZVo,6648
|
|
79
79
|
vif_plug_ovs/tests/functional/ovsdb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
-
vif_plug_ovs/tests/functional/ovsdb/test_ovsdb_lib.py,sha256=
|
|
80
|
+
vif_plug_ovs/tests/functional/ovsdb/test_ovsdb_lib.py,sha256=oB06rO9KgezJ5fe4kxsKANkC6b7sqKkzSyO2_M-Q8gw,13513
|
|
81
81
|
vif_plug_ovs/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
82
82
|
vif_plug_ovs/tests/unit/test_linux_net.py,sha256=B3buNpn9EKZQPio5rNrIma_E5MUL9vBspdg5EqZ3RHk,17532
|
|
83
|
-
vif_plug_ovs/tests/unit/test_plugin.py,sha256=
|
|
83
|
+
vif_plug_ovs/tests/unit/test_plugin.py,sha256=6Nk8Dsv-DlmhXofSnb_f8Qs6SCDGzMRu4SEUShxwWaw,31199
|
|
84
84
|
vif_plug_ovs/tests/unit/ovsdb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
85
|
vif_plug_ovs/tests/unit/ovsdb/test_ovsdb_lib.py,sha256=rNPmkH_xkGCrRDeUV_xQEAJ6A7sOH-sEGXvPYju1zwk,10705
|
|
86
|
-
os_vif-3.
|
|
87
|
-
os_vif-3.
|
|
88
|
-
os_vif-3.
|
|
89
|
-
os_vif-3.
|
|
90
|
-
os_vif-3.
|
|
91
|
-
os_vif-3.
|
|
92
|
-
os_vif-3.
|
|
93
|
-
os_vif-3.
|
|
86
|
+
os_vif-3.2.0.dist-info/AUTHORS,sha256=pqvtQTCtkonuLkD0R1k5wJdehEO19mDpXtHaSQh-Axs,3132
|
|
87
|
+
os_vif-3.2.0.dist-info/LICENSE,sha256=XfKg2H1sVi8OoRxoisUlMqoo10TKvHmU_wU39ks7MyA,10143
|
|
88
|
+
os_vif-3.2.0.dist-info/METADATA,sha256=7a_Hm63QMuaPZXD1GdhMafB_7tfNxVpINHuPfIj7YTQ,2266
|
|
89
|
+
os_vif-3.2.0.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
|
90
|
+
os_vif-3.2.0.dist-info/entry_points.txt,sha256=UhIaj_WPv49yG316SjjDuMlSqGvym-_TVYEn5JKlEaQ,207
|
|
91
|
+
os_vif-3.2.0.dist-info/pbr.json,sha256=yPKC04UCFJTK52u4xAajBv7s59GkiBMmvEbGu6qAjW0,46
|
|
92
|
+
os_vif-3.2.0.dist-info/top_level.txt,sha256=ULBxtkTk3bkfzCSYJjifWehfjJdMODVzC6SX5l_CNKo,56
|
|
93
|
+
os_vif-3.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"git_version": "da742a8", "is_release": true}
|
vif_plug_ovs/ovs.py
CHANGED
|
@@ -102,7 +102,26 @@ class OvsPlugin(plugin.PluginBase):
|
|
|
102
102
|
'bridge. This is experimental and controls the plugging '
|
|
103
103
|
'behavior when not using hybrid-plug.'
|
|
104
104
|
'This is only used on linux and should be set to false '
|
|
105
|
-
'in all other cases such as ironic smartnic ports.')
|
|
105
|
+
'in all other cases such as ironic smartnic ports.'),
|
|
106
|
+
cfg.StrOpt('default_qos_type',
|
|
107
|
+
choices=[
|
|
108
|
+
'linux-htb', 'linux-hfsc', 'linux-sfq', 'linux-codel',
|
|
109
|
+
'linux-fq_codel', 'linux-noop'
|
|
110
|
+
],
|
|
111
|
+
default='linux-noop',
|
|
112
|
+
help="""
|
|
113
|
+
The default qos type to apply to ovs ports.
|
|
114
|
+
linux-noop is the default. ovs will not modify
|
|
115
|
+
the qdisc on the port if linux-noop is specified.
|
|
116
|
+
This allows operators to manage QOS out of band
|
|
117
|
+
of OVS. For more information see the ovs man pages
|
|
118
|
+
https://manpages.debian.org/testing/openvswitch-common/ovs-vswitchd.conf.db.5.en.html#type~4
|
|
119
|
+
|
|
120
|
+
Note: This will only be set when a port is first created
|
|
121
|
+
on the ovs bridge to ensure that the qos type can be
|
|
122
|
+
managed via neutron if required for bandwidth limiting
|
|
123
|
+
and other use-cases.
|
|
124
|
+
"""),
|
|
106
125
|
)
|
|
107
126
|
|
|
108
127
|
def __init__(self, config):
|
|
@@ -159,6 +178,14 @@ class OvsPlugin(plugin.PluginBase):
|
|
|
159
178
|
return vif.network.mtu
|
|
160
179
|
return self.config.network_device_mtu
|
|
161
180
|
|
|
181
|
+
def supports_tc_qdisc(self, vif) -> bool:
|
|
182
|
+
if self._get_vif_datapath_type(vif) != constants.OVS_DATAPATH_SYSTEM:
|
|
183
|
+
return False
|
|
184
|
+
if sys.platform == constants.PLATFORM_WIN32:
|
|
185
|
+
return False
|
|
186
|
+
|
|
187
|
+
return True
|
|
188
|
+
|
|
162
189
|
def _create_vif_port(self, vif, vif_name, instance_info, **kwargs):
|
|
163
190
|
mtu = self._get_mtu(vif)
|
|
164
191
|
# NOTE(sean-k-mooney): As part of a partial fix to bug #1734320
|
|
@@ -175,6 +202,19 @@ class OvsPlugin(plugin.PluginBase):
|
|
|
175
202
|
# can be enabled automatically in the future.
|
|
176
203
|
if self.config.isolate_vif:
|
|
177
204
|
kwargs['tag'] = constants.DEAD_VLAN
|
|
205
|
+
qos_type = self._get_qos_type(vif)
|
|
206
|
+
if qos_type is not None:
|
|
207
|
+
# NOTE(sean-k-mooney): If the port is not already created
|
|
208
|
+
# on the bridge we need to set the default qos type to
|
|
209
|
+
# ensure that the port is created with the correct qos
|
|
210
|
+
# type. This is only needed for the linux kernel datapath
|
|
211
|
+
# as the qos type is not managed by neutron for the other
|
|
212
|
+
# datapaths.
|
|
213
|
+
# This is a mitigation for the performance regression
|
|
214
|
+
# introduced by the fix for bug #1734320. See bug #2017868
|
|
215
|
+
# for more details.
|
|
216
|
+
if not self.ovsdb.port_exists(vif_name, vif.network.bridge):
|
|
217
|
+
kwargs['qos_type'] = qos_type
|
|
178
218
|
bridge = kwargs.pop('bridge', vif.network.bridge)
|
|
179
219
|
self.ovsdb.create_ovs_vif_port(
|
|
180
220
|
bridge,
|
|
@@ -382,9 +422,18 @@ class OvsPlugin(plugin.PluginBase):
|
|
|
382
422
|
|
|
383
423
|
linux_net.delete_bridge(linux_bridge_name, v1_name)
|
|
384
424
|
|
|
385
|
-
self.
|
|
425
|
+
qos_type = self._get_qos_type(vif)
|
|
426
|
+
self.ovsdb.delete_ovs_vif_port(
|
|
427
|
+
vif.network.bridge, v2_name, qos_type=qos_type
|
|
428
|
+
)
|
|
386
429
|
self._delete_bridge_if_trunk(vif)
|
|
387
430
|
|
|
431
|
+
def _get_qos_type(self, vif):
|
|
432
|
+
qos_type = None
|
|
433
|
+
if self.supports_tc_qdisc(vif):
|
|
434
|
+
qos_type = self.config.default_qos_type
|
|
435
|
+
return qos_type
|
|
436
|
+
|
|
388
437
|
def _unplug_vif_windows(self, vif, instance_info):
|
|
389
438
|
"""Remove port from OVS."""
|
|
390
439
|
self.ovsdb.delete_ovs_vif_port(vif.network.bridge, vif.id,
|
|
@@ -400,7 +449,10 @@ class OvsPlugin(plugin.PluginBase):
|
|
|
400
449
|
int_bridge_patch = self.gen_port_name('ibp', vif.id, max_length=64)
|
|
401
450
|
self.ovsdb.delete_ovs_vif_port(vif.network.bridge, int_bridge_patch)
|
|
402
451
|
self.ovsdb.delete_ovs_vif_port(port_bridge_name, port_bridge_patch)
|
|
403
|
-
self.
|
|
452
|
+
qos_type = self._get_qos_type(vif)
|
|
453
|
+
self.ovsdb.delete_ovs_vif_port(
|
|
454
|
+
port_bridge_name, vif.vif_name, qos_type=qos_type
|
|
455
|
+
)
|
|
404
456
|
self.ovsdb.delete_ovs_bridge(port_bridge_name)
|
|
405
457
|
self._delete_bridge_if_trunk(vif)
|
|
406
458
|
|
|
@@ -409,7 +461,10 @@ class OvsPlugin(plugin.PluginBase):
|
|
|
409
461
|
# NOTE(sean-k-mooney): even with the partial revert of change
|
|
410
462
|
# Iaf15fa7a678ec2624f7c12f634269c465fbad930 this should be correct
|
|
411
463
|
# so this is not removed.
|
|
412
|
-
self.
|
|
464
|
+
qos_type = self._get_qos_type(vif)
|
|
465
|
+
self.ovsdb.delete_ovs_vif_port(
|
|
466
|
+
vif.network.bridge, vif.vif_name, qos_type=qos_type
|
|
467
|
+
)
|
|
413
468
|
self._delete_bridge_if_trunk(vif)
|
|
414
469
|
|
|
415
470
|
def _unplug_vf(self, vif):
|
|
@@ -428,8 +483,11 @@ class OvsPlugin(plugin.PluginBase):
|
|
|
428
483
|
# The representor interface can't be deleted because it bind the
|
|
429
484
|
# SR-IOV VF, therefore we just need to remove it from the ovs bridge
|
|
430
485
|
# and set the status to down
|
|
486
|
+
qos_type = self._get_qos_type(vif)
|
|
431
487
|
self.ovsdb.delete_ovs_vif_port(
|
|
432
|
-
vif.network.bridge, representor, delete_netdev=False
|
|
488
|
+
vif.network.bridge, representor, delete_netdev=False,
|
|
489
|
+
qos_type=qos_type
|
|
490
|
+
)
|
|
433
491
|
if datapath == constants.OVS_DATAPATH_SYSTEM:
|
|
434
492
|
linux_net.set_interface_state(representor, 'down')
|
|
435
493
|
self._delete_bridge_if_trunk(vif)
|
vif_plug_ovs/ovsdb/impl_idl.py
CHANGED
|
@@ -23,7 +23,7 @@ from ovsdbapp.schema.open_vswitch import impl_idl
|
|
|
23
23
|
|
|
24
24
|
from vif_plug_ovs.ovsdb import api
|
|
25
25
|
|
|
26
|
-
REQUIRED_TABLES = ('Interface', 'Port', 'Bridge', 'Open_vSwitch')
|
|
26
|
+
REQUIRED_TABLES = ('Interface', 'Port', 'Bridge', 'Open_vSwitch', 'QoS')
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def idl_factory(config):
|
|
@@ -48,6 +48,7 @@ class NeutronOvsdbIdl(impl_idl.OvsdbIdl, api.ImplAPI):
|
|
|
48
48
|
This class provides an OVSDB IDL (Open vSwitch Database Interface
|
|
49
49
|
Definition Language) interface to the OVS back-end.
|
|
50
50
|
"""
|
|
51
|
+
|
|
51
52
|
def __init__(self, conn):
|
|
52
53
|
vlog.use_python_logger()
|
|
53
54
|
super(NeutronOvsdbIdl, self).__init__(conn)
|
vif_plug_ovs/ovsdb/ovsdb_lib.py
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# under the License.
|
|
12
12
|
|
|
13
13
|
import sys
|
|
14
|
+
import uuid
|
|
14
15
|
|
|
15
16
|
from oslo_log import log as logging
|
|
16
17
|
|
|
@@ -20,6 +21,7 @@ from vif_plug_ovs.ovsdb import api as ovsdb_api
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
LOG = logging.getLogger(__name__)
|
|
24
|
+
QOS_UUID_NAMESPACE = uuid.UUID("68da264a-847f-42a8-8ab0-5e774aee3d95")
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
class BaseOVS(object):
|
|
@@ -142,7 +144,8 @@ class BaseOVS(object):
|
|
|
142
144
|
def create_ovs_vif_port(
|
|
143
145
|
self, bridge, dev, iface_id, mac, instance_id,
|
|
144
146
|
mtu=None, interface_type=None, vhost_server_path=None,
|
|
145
|
-
tag=None, pf_pci=None, vf_num=None, set_ids=True, datapath_type=None
|
|
147
|
+
tag=None, pf_pci=None, vf_num=None, set_ids=True, datapath_type=None,
|
|
148
|
+
qos_type=None
|
|
146
149
|
):
|
|
147
150
|
"""Create OVS port
|
|
148
151
|
|
|
@@ -159,6 +162,7 @@ class BaseOVS(object):
|
|
|
159
162
|
:param vf_num: VF number of PF for dpdk representor port.
|
|
160
163
|
:param set_ids: set external ids on port (bool).
|
|
161
164
|
:param datapath_type: datapath type for port's bridge
|
|
165
|
+
:param qos_type: qos type for a port
|
|
162
166
|
|
|
163
167
|
.. note:: create DPDK representor port by setting all three values:
|
|
164
168
|
`interface_type`, `pf_pci` and `vf_num`. if interface type is
|
|
@@ -181,6 +185,24 @@ class BaseOVS(object):
|
|
|
181
185
|
PF_PCI=pf_pci, VF_NUM=vf_num)
|
|
182
186
|
col_values.append(('options',
|
|
183
187
|
{'dpdk-devargs': devargs_string}))
|
|
188
|
+
# create qos record if qos type is specified
|
|
189
|
+
# and get the qos id. This is done outside of the transaction
|
|
190
|
+
# because we need the qos id to set the qos on the port.
|
|
191
|
+
# The qos uuid cannot be set when creating the record so we
|
|
192
|
+
# have to look it up after the record is created. this means
|
|
193
|
+
# we need to create the qos record outside of the transaction
|
|
194
|
+
# that creates the port.
|
|
195
|
+
qid = None
|
|
196
|
+
if qos_type:
|
|
197
|
+
self.delete_qos_if_exists(dev, qos_type)
|
|
198
|
+
qos_id = uuid.uuid5(QOS_UUID_NAMESPACE, dev)
|
|
199
|
+
qos_external_ids = {'id': str(qos_id), '_type': qos_type}
|
|
200
|
+
self.ovsdb.db_create(
|
|
201
|
+
'QoS', type=qos_type, external_ids=qos_external_ids
|
|
202
|
+
).execute(check_error=True)
|
|
203
|
+
record = self.get_qos(dev, qos_type)
|
|
204
|
+
qid = record[0]['_uuid']
|
|
205
|
+
|
|
184
206
|
with self.ovsdb.transaction() as txn:
|
|
185
207
|
if datapath_type:
|
|
186
208
|
txn.add(self.ovsdb.add_br(bridge, may_exist=True,
|
|
@@ -188,19 +210,46 @@ class BaseOVS(object):
|
|
|
188
210
|
txn.add(self.ovsdb.add_port(bridge, dev))
|
|
189
211
|
if tag:
|
|
190
212
|
txn.add(self.ovsdb.db_set('Port', dev, ('tag', tag)))
|
|
213
|
+
if qid:
|
|
214
|
+
txn.add(self.ovsdb.db_set('Port', dev, ('qos', qid)))
|
|
191
215
|
if col_values:
|
|
192
216
|
txn.add(self.ovsdb.db_set('Interface', dev, *col_values))
|
|
193
217
|
self.update_device_mtu(
|
|
194
218
|
txn, dev, mtu, interface_type=interface_type
|
|
195
219
|
)
|
|
196
220
|
|
|
221
|
+
def port_exists(self, port_name, bridge):
|
|
222
|
+
ports = self.ovsdb.list_ports(bridge).execute()
|
|
223
|
+
return ports is not None and port_name in ports
|
|
224
|
+
|
|
225
|
+
def get_qos(self, dev, qos_type):
|
|
226
|
+
qos_id = uuid.uuid5(QOS_UUID_NAMESPACE, dev)
|
|
227
|
+
external_ids = {'id': str(qos_id), '_type': qos_type}
|
|
228
|
+
return self.ovsdb.db_find(
|
|
229
|
+
'QoS', ('external_ids', '=', external_ids),
|
|
230
|
+
colmuns=['_uuid']
|
|
231
|
+
).execute()
|
|
232
|
+
|
|
233
|
+
def delete_qos_if_exists(self, dev, qos_type):
|
|
234
|
+
qos_ids = self.get_qos(dev, qos_type)
|
|
235
|
+
if qos_ids is not None and len(qos_ids) > 0:
|
|
236
|
+
for qos_id in qos_ids:
|
|
237
|
+
if '_uuid' in qos_id:
|
|
238
|
+
self.ovsdb.db_destroy(
|
|
239
|
+
'QoS', str(qos_id['_uuid'])
|
|
240
|
+
).execute()
|
|
241
|
+
|
|
197
242
|
def update_ovs_vif_port(self, dev, mtu=None, interface_type=None):
|
|
198
243
|
with self.ovsdb.transaction() as txn:
|
|
199
244
|
self.update_device_mtu(
|
|
200
245
|
txn, dev, mtu, interface_type=interface_type
|
|
201
246
|
)
|
|
202
247
|
|
|
203
|
-
def delete_ovs_vif_port(
|
|
248
|
+
def delete_ovs_vif_port(
|
|
249
|
+
self, bridge, dev, delete_netdev=True, qos_type=None
|
|
250
|
+
):
|
|
204
251
|
self.ovsdb.del_port(dev, bridge=bridge, if_exists=True).execute()
|
|
252
|
+
if qos_type:
|
|
253
|
+
self.delete_qos_if_exists(dev, qos_type)
|
|
205
254
|
if delete_netdev:
|
|
206
255
|
linux_net.delete_net_dev(dev)
|
|
@@ -25,6 +25,22 @@ class VifPlugOvsBaseFunctionalTestCase(os_vif_base.BaseFunctionalTestCase):
|
|
|
25
25
|
def _check_bridge(self, name):
|
|
26
26
|
return self._ovsdb.br_exists(name).execute()
|
|
27
27
|
|
|
28
|
+
def _check_port(self, name, bridge):
|
|
29
|
+
return self.ovs.port_exists(name, bridge)
|
|
30
|
+
|
|
31
|
+
def _check_parameter(self, table, port, parameter, expected_value):
|
|
32
|
+
def get_value():
|
|
33
|
+
return self._ovsdb.db_get(table, port, parameter).execute()
|
|
34
|
+
|
|
35
|
+
def check_value():
|
|
36
|
+
val = get_value()
|
|
37
|
+
return val == expected_value
|
|
38
|
+
self.assertTrue(
|
|
39
|
+
wait_until_true(check_value, timeout=2, sleep=0.5),
|
|
40
|
+
f"Parameter {parameter} of {table} {port} is {get_value()} "
|
|
41
|
+
f"not {expected_value}"
|
|
42
|
+
)
|
|
43
|
+
|
|
28
44
|
def _add_bridge(self, name, may_exist=True, datapath_type=None):
|
|
29
45
|
self._ovsdb.add_br(name, may_exist=may_exist,
|
|
30
46
|
datapath_type=datapath_type).execute()
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
# License for the specific language governing permissions and limitations
|
|
11
11
|
# under the License.
|
|
12
12
|
|
|
13
|
+
import fixtures
|
|
13
14
|
import random
|
|
14
15
|
|
|
16
|
+
|
|
15
17
|
from unittest import mock
|
|
16
18
|
|
|
17
19
|
import testscenarios
|
|
@@ -19,7 +21,6 @@ import testscenarios
|
|
|
19
21
|
from oslo_concurrency import processutils
|
|
20
22
|
from oslo_config import cfg
|
|
21
23
|
from oslo_utils import uuidutils
|
|
22
|
-
from ovsdbapp.schema.open_vswitch import impl_idl
|
|
23
24
|
|
|
24
25
|
from vif_plug_ovs import constants
|
|
25
26
|
from vif_plug_ovs import linux_net
|
|
@@ -59,17 +60,17 @@ class TestOVSDBLib(testscenarios.WithScenarios,
|
|
|
59
60
|
self.interface)
|
|
60
61
|
|
|
61
62
|
# Make sure exceptions pass through by calling do_post_commit directly
|
|
62
|
-
|
|
63
|
-
impl_idl.
|
|
64
|
-
|
|
63
|
+
post_commit = (
|
|
64
|
+
'ovsdbapp.schema.open_vswitch.impl_idl.'
|
|
65
|
+
'OvsVsctlTransaction.post_commit'
|
|
66
|
+
)
|
|
67
|
+
# "this" is the self parmater which is a reference to the
|
|
68
|
+
# OvsVsctlTransaction instance on which do_post_commit is defiend.
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return (self._ovsdb.db_get(
|
|
69
|
-
table, port, parameter).execute() == expected_value)
|
|
70
|
+
def direct_post_commit(this, transaction):
|
|
71
|
+
this.do_post_commit(transaction)
|
|
70
72
|
|
|
71
|
-
self.
|
|
72
|
-
sleep=0.5))
|
|
73
|
+
self.useFixture(fixtures.MonkeyPatch(post_commit, direct_post_commit))
|
|
73
74
|
|
|
74
75
|
def _add_port(self, bridge, port, may_exist=True):
|
|
75
76
|
with self._ovsdb.transaction() as txn:
|
|
@@ -122,11 +123,11 @@ class TestOVSDBLib(testscenarios.WithScenarios,
|
|
|
122
123
|
expected_external_ids)
|
|
123
124
|
self._check_parameter('Interface', port_name, 'type', interface_type)
|
|
124
125
|
expected_vhost_server_path = {'vhost-server-path': vhost_server_path}
|
|
125
|
-
self._check_parameter(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
expected_vhost_server_path)
|
|
126
|
+
self._check_parameter(
|
|
127
|
+
'Interface', port_name, 'options', expected_vhost_server_path
|
|
128
|
+
)
|
|
129
129
|
self._check_parameter('Port', port_name, 'tag', 2000)
|
|
130
|
+
self._check_parameter('Port', port_name, 'qos', [])
|
|
130
131
|
|
|
131
132
|
@mock.patch.object(linux_net, 'delete_net_dev')
|
|
132
133
|
def test_delete_ovs_vif_port(self, *mock):
|
|
@@ -180,3 +181,156 @@ class TestOVSDBLib(testscenarios.WithScenarios,
|
|
|
180
181
|
port_opts = {'peer': int_bridge_port}
|
|
181
182
|
self._check_parameter(
|
|
182
183
|
'Interface', port_bridge_port, 'options', port_opts)
|
|
184
|
+
|
|
185
|
+
def test_create_ovs_vif_port_with_default_qos(self):
|
|
186
|
+
port_name = 'qos-port-' + self.interface
|
|
187
|
+
iface_id = 'iface_id'
|
|
188
|
+
mac = 'ca:fe:ca:fe:ca:fe'
|
|
189
|
+
instance_id = uuidutils.generate_uuid()
|
|
190
|
+
mtu = 1500
|
|
191
|
+
interface_type = 'internal'
|
|
192
|
+
qos_type = CONF.os_vif_ovs.default_qos_type
|
|
193
|
+
|
|
194
|
+
self.addCleanup(self._del_bridge, self.brname)
|
|
195
|
+
self._add_bridge(self.brname)
|
|
196
|
+
|
|
197
|
+
self.addCleanup(
|
|
198
|
+
self.ovs.delete_ovs_vif_port, self.brname, port_name,
|
|
199
|
+
delete_netdev=False, qos_type=qos_type
|
|
200
|
+
)
|
|
201
|
+
self.ovs.create_ovs_vif_port(
|
|
202
|
+
self.brname, port_name, iface_id, mac,
|
|
203
|
+
instance_id, mtu=mtu, interface_type=interface_type,
|
|
204
|
+
tag=2000, qos_type=qos_type
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# first we assert that the standard parameters are set correctly
|
|
208
|
+
expected_external_ids = {'iface-status': 'active',
|
|
209
|
+
'iface-id': iface_id,
|
|
210
|
+
'attached-mac': mac,
|
|
211
|
+
'vm-uuid': instance_id}
|
|
212
|
+
self._check_parameter('Interface', port_name, 'external_ids',
|
|
213
|
+
expected_external_ids)
|
|
214
|
+
self._check_parameter('Interface', port_name, 'type', interface_type)
|
|
215
|
+
self._check_parameter('Port', port_name, 'tag', 2000)
|
|
216
|
+
|
|
217
|
+
# now we check that the port has a qos policy attached
|
|
218
|
+
qos_uuid = self.ovs.get_qos(
|
|
219
|
+
port_name, qos_type
|
|
220
|
+
)[0]['_uuid']
|
|
221
|
+
self._check_parameter('Port', port_name, 'qos', qos_uuid)
|
|
222
|
+
|
|
223
|
+
# finally we check that the qos policy has the correct parameters
|
|
224
|
+
self._check_parameter(
|
|
225
|
+
'QoS', str(qos_uuid), 'type', qos_type
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
def test_delete_qos_if_exists(self):
|
|
229
|
+
port_name = 'del-qos-port-' + self.interface
|
|
230
|
+
iface_id = 'iface_id'
|
|
231
|
+
mac = 'ca:fe:ca:fe:ca:fe'
|
|
232
|
+
instance_id = uuidutils.generate_uuid()
|
|
233
|
+
interface_type = 'internal'
|
|
234
|
+
qos_type = CONF.os_vif_ovs.default_qos_type
|
|
235
|
+
|
|
236
|
+
# setup test by creating a bridge and port, and register
|
|
237
|
+
# cleanup funcitons to avoid leaking them.
|
|
238
|
+
self.addCleanup(self._del_bridge, self.brname)
|
|
239
|
+
self._add_bridge(self.brname)
|
|
240
|
+
self.addCleanup(
|
|
241
|
+
self.ovs.delete_ovs_vif_port, self.brname, port_name,
|
|
242
|
+
delete_netdev=False, qos_type=qos_type
|
|
243
|
+
)
|
|
244
|
+
self.ovs.create_ovs_vif_port(
|
|
245
|
+
self.brname, port_name, iface_id, mac,
|
|
246
|
+
instance_id, interface_type=interface_type,
|
|
247
|
+
qos_type=qos_type
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
# now we check that the port has a qos policy attached
|
|
251
|
+
qos_uuid = self.ovs.get_qos(
|
|
252
|
+
port_name, CONF.os_vif_ovs.default_qos_type
|
|
253
|
+
)[0]['_uuid']
|
|
254
|
+
self._check_parameter('Port', port_name, 'qos', qos_uuid)
|
|
255
|
+
|
|
256
|
+
# finally we check that the qos policy has the correct parameters
|
|
257
|
+
self._check_parameter(
|
|
258
|
+
'QoS', str(qos_uuid), 'type', qos_type
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
# we need to delete the port directly in the db to remove
|
|
262
|
+
# any references to the qos policy
|
|
263
|
+
self.ovs.ovsdb.del_port(
|
|
264
|
+
port_name, bridge=self.brname, if_exists=True).execute()
|
|
265
|
+
# then we can delete the qos policy
|
|
266
|
+
self.ovs.delete_qos_if_exists(port_name, qos_type)
|
|
267
|
+
self._check_parameter(
|
|
268
|
+
'QoS', str(qos_uuid), 'type', None
|
|
269
|
+
)
|
|
270
|
+
# invoking the delete when the policy does not exist
|
|
271
|
+
# should not result in an error
|
|
272
|
+
self.ovs.delete_qos_if_exists(port_name, qos_type)
|
|
273
|
+
self._check_parameter(
|
|
274
|
+
'QoS', str(qos_uuid), 'type', None
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
def test_get_qos(self):
|
|
278
|
+
port_name = 'get-qos-' + self.interface
|
|
279
|
+
iface_id = 'iface_id'
|
|
280
|
+
mac = 'ca:fe:ca:fe:ca:fe'
|
|
281
|
+
instance_id = uuidutils.generate_uuid()
|
|
282
|
+
interface_type = 'internal'
|
|
283
|
+
qos_type = CONF.os_vif_ovs.default_qos_type
|
|
284
|
+
# initally no qos policy should exist
|
|
285
|
+
self.assertEqual(0, len(self.ovs.get_qos(port_name, qos_type)))
|
|
286
|
+
|
|
287
|
+
# if we create a port with a qos policy get_qos should
|
|
288
|
+
# return the policy
|
|
289
|
+
self.addCleanup(self._del_bridge, self.brname)
|
|
290
|
+
self._add_bridge(self.brname)
|
|
291
|
+
self.addCleanup(
|
|
292
|
+
self.ovs.delete_ovs_vif_port, self.brname, port_name,
|
|
293
|
+
delete_netdev=False, qos_type=qos_type
|
|
294
|
+
)
|
|
295
|
+
self.ovs.create_ovs_vif_port(
|
|
296
|
+
self.brname, port_name, iface_id, mac,
|
|
297
|
+
instance_id, interface_type=interface_type,
|
|
298
|
+
qos_type=qos_type
|
|
299
|
+
)
|
|
300
|
+
# result should be a list of lenght 1 containing the
|
|
301
|
+
# qos policy created for the port we defied.
|
|
302
|
+
result = self.ovs.get_qos(port_name, qos_type)
|
|
303
|
+
self.assertEqual(1, len(result))
|
|
304
|
+
self.assertIn('_uuid', result[0])
|
|
305
|
+
self._check_parameter(
|
|
306
|
+
'Port', port_name, 'qos', result[0]['_uuid']
|
|
307
|
+
)
|
|
308
|
+
# if we delete the port and its qos policy get_qos should
|
|
309
|
+
# not return it.
|
|
310
|
+
self.ovs.delete_ovs_vif_port(
|
|
311
|
+
self.brname, port_name,
|
|
312
|
+
delete_netdev=False, qos_type=qos_type
|
|
313
|
+
)
|
|
314
|
+
self.assertEqual(0, len(self.ovs.get_qos(port_name, qos_type)))
|
|
315
|
+
|
|
316
|
+
def test_port_exists(self):
|
|
317
|
+
port_name = 'port-exists-' + self.interface
|
|
318
|
+
iface_id = 'iface_id'
|
|
319
|
+
mac = 'ca:fe:ca:fe:ca:fe'
|
|
320
|
+
instance_id = uuidutils.generate_uuid()
|
|
321
|
+
interface_type = 'internal'
|
|
322
|
+
|
|
323
|
+
self.assertFalse(self.ovs.port_exists(port_name, self.brname))
|
|
324
|
+
|
|
325
|
+
self.addCleanup(self._del_bridge, self.brname)
|
|
326
|
+
self._add_bridge(self.brname)
|
|
327
|
+
self.addCleanup(
|
|
328
|
+
self.ovs.delete_ovs_vif_port, self.brname, port_name,
|
|
329
|
+
delete_netdev=False,
|
|
330
|
+
)
|
|
331
|
+
self.ovs.create_ovs_vif_port(
|
|
332
|
+
self.brname, port_name, iface_id, mac,
|
|
333
|
+
instance_id, interface_type=interface_type,
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
self.assertTrue(self.ovs.port_exists(port_name, self.brname))
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# under the License.
|
|
12
12
|
|
|
13
13
|
import testscenarios
|
|
14
|
+
import time
|
|
14
15
|
|
|
15
16
|
from oslo_concurrency import processutils
|
|
16
17
|
from oslo_config import cfg
|
|
@@ -33,6 +34,41 @@ def run_privileged(*full_args):
|
|
|
33
34
|
return processutils.execute(*full_args)[0].rstrip()
|
|
34
35
|
|
|
35
36
|
|
|
37
|
+
# derived from test_impl_pyroute2
|
|
38
|
+
|
|
39
|
+
def exist_device(device):
|
|
40
|
+
try:
|
|
41
|
+
run_privileged('ip', 'link', 'show', device)
|
|
42
|
+
return True
|
|
43
|
+
except processutils.ProcessExecutionError as e:
|
|
44
|
+
if e.exit_code == 1:
|
|
45
|
+
return False
|
|
46
|
+
raise
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def add_device(device, dev_type, peer=None, link=None,
|
|
50
|
+
vlan_id=None):
|
|
51
|
+
if 'vlan' == dev_type:
|
|
52
|
+
run_privileged('ip', 'link', 'add', 'link', link,
|
|
53
|
+
'name', device, 'type', dev_type, 'vlan', 'id',
|
|
54
|
+
vlan_id)
|
|
55
|
+
elif 'veth' == dev_type:
|
|
56
|
+
run_privileged('ip', 'link', 'add', device, 'type', dev_type,
|
|
57
|
+
'peer', 'name', peer)
|
|
58
|
+
elif 'dummy' == dev_type:
|
|
59
|
+
run_privileged('ip', 'link', 'add', device, 'type', dev_type)
|
|
60
|
+
# ensure that the device exists to prevent racing with other ip commands
|
|
61
|
+
for _ in range(10):
|
|
62
|
+
if exist_device(device):
|
|
63
|
+
return
|
|
64
|
+
time.sleep(0.1)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def del_device(device):
|
|
68
|
+
if exist_device(device):
|
|
69
|
+
run_privileged('ip', 'link', 'del', device)
|
|
70
|
+
|
|
71
|
+
|
|
36
72
|
class TestOVSPlugin(testscenarios.WithScenarios,
|
|
37
73
|
base.VifPlugOvsBaseFunctionalTestCase):
|
|
38
74
|
|
|
@@ -82,6 +118,24 @@ class TestOVSPlugin(testscenarios.WithScenarios,
|
|
|
82
118
|
mode='client',
|
|
83
119
|
port_profile=self.profile_ovs)
|
|
84
120
|
|
|
121
|
+
self.profile_ovs_system = objects.vif.VIFPortProfileOpenVSwitch(
|
|
122
|
+
interface_id='e65867e0-9340-4a7f-a256-09af6eb7a3aa',
|
|
123
|
+
datapath_type='system',
|
|
124
|
+
create_port=True)
|
|
125
|
+
|
|
126
|
+
self.network_ovs = objects.network.Network(
|
|
127
|
+
id='437c6db5-4e6f-4b43-b64b-ed6a11ee5ba7',
|
|
128
|
+
bridge='br-qos-' + self.interface,
|
|
129
|
+
subnets=self.subnets,
|
|
130
|
+
vlan=99)
|
|
131
|
+
|
|
132
|
+
self.vif_ovs_port = objects.vif.VIFOpenVSwitch(
|
|
133
|
+
id='b679325f-ca89-4ee0-a8be-6db1409b69ea',
|
|
134
|
+
address='ca:fe:de:ad:be:ef',
|
|
135
|
+
network=self.network_ovs,
|
|
136
|
+
port_profile=self.profile_ovs_system,
|
|
137
|
+
vif_name="qos-port-" + self.interface)
|
|
138
|
+
|
|
85
139
|
self.instance = objects.instance_info.InstanceInfo(
|
|
86
140
|
name='demo',
|
|
87
141
|
uuid='f0000000-0000-0000-0000-000000000001')
|
|
@@ -98,3 +152,34 @@ class TestOVSPlugin(testscenarios.WithScenarios,
|
|
|
98
152
|
self.plugin.unplug(self.vif_vhostuser_trunk, self.instance)
|
|
99
153
|
self.assertTrue(self._check_bridge(other_bridge))
|
|
100
154
|
self.assertFalse(self._check_bridge(trunk_bridge))
|
|
155
|
+
|
|
156
|
+
def test_plug_unplug_ovs_port_with_qos(self):
|
|
157
|
+
bridge = 'br-qos-' + self.interface
|
|
158
|
+
vif_name = "qos-port-" + self.interface
|
|
159
|
+
qos_type = CONF.os_vif_ovs.default_qos_type
|
|
160
|
+
self.addCleanup(self._del_bridge, bridge)
|
|
161
|
+
self.addCleanup(
|
|
162
|
+
self.ovs.delete_ovs_vif_port, bridge, vif_name,
|
|
163
|
+
delete_netdev=False, qos_type=qos_type
|
|
164
|
+
)
|
|
165
|
+
self.addCleanup(del_device, vif_name)
|
|
166
|
+
add_device(vif_name, 'dummy')
|
|
167
|
+
# pluging a vif will create the port and bridge
|
|
168
|
+
# if either does not exist
|
|
169
|
+
self.plugin.plug(self.vif_ovs_port, self.instance)
|
|
170
|
+
self.assertTrue(self._check_bridge(bridge))
|
|
171
|
+
self.assertTrue(self._check_port(vif_name, bridge))
|
|
172
|
+
qos_uuid = self.ovs.get_qos(
|
|
173
|
+
vif_name, qos_type
|
|
174
|
+
)[0]['_uuid']
|
|
175
|
+
self._check_parameter('Port', vif_name, 'qos', qos_uuid)
|
|
176
|
+
self._check_parameter(
|
|
177
|
+
'QoS', str(qos_uuid), 'type', qos_type
|
|
178
|
+
)
|
|
179
|
+
# unpluging a port will not delete the bridge.
|
|
180
|
+
self.plugin.unplug(self.vif_ovs_port, self.instance)
|
|
181
|
+
self.assertTrue(self._check_bridge(bridge))
|
|
182
|
+
self.assertFalse(self._check_port(vif_name, bridge))
|
|
183
|
+
self._check_parameter(
|
|
184
|
+
'QoS', str(qos_uuid), 'type', None
|
|
185
|
+
)
|
|
@@ -362,7 +362,9 @@ class PluginTest(testtools.TestCase):
|
|
|
362
362
|
delete_ovs_vif_port, delete_ovs_bridge):
|
|
363
363
|
calls = {
|
|
364
364
|
'delete_bridge': [mock.call('qbrvif-xxx-yyy', 'qvbb679325f-ca')],
|
|
365
|
-
'delete_ovs_vif_port': [mock.call(
|
|
365
|
+
'delete_ovs_vif_port': [mock.call(
|
|
366
|
+
'br0', 'qvob679325f-ca', qos_type='linux-noop'
|
|
367
|
+
)]
|
|
366
368
|
}
|
|
367
369
|
mock_sys.platform = 'linux'
|
|
368
370
|
plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME)
|
|
@@ -510,8 +512,12 @@ class PluginTest(testtools.TestCase):
|
|
|
510
512
|
'get_vf_num_by_pci_address': [mock.call('0002:24:12.3')],
|
|
511
513
|
'get_representor_port': [mock.call('eth0', '2')],
|
|
512
514
|
'set_interface_state': [mock.call('eth0_2', 'down')],
|
|
513
|
-
'delete_ovs_vif_port': [
|
|
514
|
-
|
|
515
|
+
'delete_ovs_vif_port': [
|
|
516
|
+
mock.call(
|
|
517
|
+
'br0', 'eth0_2', delete_netdev=False,
|
|
518
|
+
qos_type='linux-noop'
|
|
519
|
+
)
|
|
520
|
+
]
|
|
515
521
|
}
|
|
516
522
|
|
|
517
523
|
get_ifname_by_pci_address.return_value = 'eth0'
|
|
@@ -602,8 +608,13 @@ class PluginTest(testtools.TestCase):
|
|
|
602
608
|
calls = {
|
|
603
609
|
'get_dpdk_representor_port_name': [mock.call(
|
|
604
610
|
self.vif_ovs_vf_dpdk.id)],
|
|
605
|
-
'delete_ovs_vif_port': [
|
|
606
|
-
|
|
611
|
+
'delete_ovs_vif_port': [
|
|
612
|
+
mock.call(
|
|
613
|
+
'br0', devname, delete_netdev=False,
|
|
614
|
+
qos_type=None
|
|
615
|
+
)
|
|
616
|
+
]
|
|
617
|
+
}
|
|
607
618
|
plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME)
|
|
608
619
|
plugin.unplug(self.vif_ovs_vf_dpdk, self.instance)
|
|
609
620
|
get_dpdk_representor_port_name.assert_has_calls(
|
|
@@ -636,7 +647,7 @@ class PluginTest(testtools.TestCase):
|
|
|
636
647
|
mock.call('br0', 'ibpb679325f-ca89-4ee0-a8be-6db1409b69ea'),
|
|
637
648
|
mock.call(
|
|
638
649
|
'pbb679325f-ca8', 'pbpb679325f-ca89-4ee0-a8be-6db1409b69ea'),
|
|
639
|
-
mock.call('pbb679325f-ca8', 'tap-xxx-yyy-zzz')
|
|
650
|
+
mock.call('pbb679325f-ca8', 'tap-xxx-yyy-zzz', qos_type=None)
|
|
640
651
|
]
|
|
641
652
|
delete_ovs_vif_port.assert_has_calls(calls)
|
|
642
653
|
delete_ovs_bridge.assert_called_once_with('pbb679325f-ca8')
|
os_vif-3.1.1.dist-info/pbr.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"git_version": "54bae86", "is_release": true}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|