summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Santoro <francesco.santoro@6wind.com>2015-09-28 18:43:15 +0200
committerFrancesco Santoro <francesco.santoro@6wind.com>2015-09-29 10:30:24 +0200
commitd5424ede3735e6949098008fbe46247b1ec0e8f8 (patch)
treef2eafe96baf32d79e319065b5bbb6932e97c6fcb
parentb9a132448c02f52e9c50782317bab8a1a4013236 (diff)
add monkey patch for vhostuser ports plug/unplug
This patch adds a monkey patch for nova that calls an external script (vif-ovs-fp-plug) for plugging/unplugging vhostuser ports managed by the fastpath. Moreover this patch replaces the VIF_PLUGIN_SCRIPT variable with VHOST_USER_OVS_PLUG as default way for mechanism driver to notify compute nodes for vhostuser plug/unplug Change-Id: Ic2d1b2b5bbcc439f3ab55ec6c1866b1c07d03dd1
Notes
Notes (review): Verified+2: Jenkins Code-Review+2: Maxime Leroy <maxime.leroy@6wind.com> Workflow+1: Maxime Leroy <maxime.leroy@6wind.com> Submitted-by: Jenkins Submitted-at: Tue, 29 Sep 2015 08:59:06 +0000 Reviewed-on: https://review.openstack.org/228779 Project: stackforge/networking-6wind Branch: refs/heads/master
-rw-r--r--devstack/plugin.sh8
-rw-r--r--etc/nova/rootwrap.d/6wind.filters1
-rw-r--r--networking_6wind/common/constants.py3
-rw-r--r--networking_6wind/ml2_drivers/mech_ovs_fp.py2
-rw-r--r--networking_6wind/monkey_patch/__init__.py0
-rw-r--r--networking_6wind/monkey_patch/vif.py82
-rw-r--r--networking_6wind/plug_scripts/vif_ovs_fp_plug.py56
-rw-r--r--networking_6wind/tests/unit/ml2_drivers/test_mech_ovs_fp.py4
8 files changed, 122 insertions, 34 deletions
diff --git a/devstack/plugin.sh b/devstack/plugin.sh
index b55e76a..fe5150d 100644
--- a/devstack/plugin.sh
+++ b/devstack/plugin.sh
@@ -16,6 +16,7 @@
16# start_fast_path 16# start_fast_path
17# setup_develop networking-6wind 17# setup_develop networking-6wind
18# configure_nova_rootwrap 18# configure_nova_rootwrap
19# nova_enable_monkey_patch
19# configure_ml2_for_fast_path 20# configure_ml2_for_fast_path
20# stop_fast_path 21# stop_fast_path
21 22
@@ -57,6 +58,12 @@ function nova_set_hugepages_flavor {
57 done 58 done
58} 59}
59 60
61function nova_enable_monkey_patch {
62 iniset $NOVA_CONF DEFAULT monkey_patch True
63 iniset $NOVA_CONF DEFAULT monkey_patch_modules \
64 nova.virt.libvirt.vif:networking_6wind.monkey_patch.vif.decorator
65}
66
60# main loop 67# main loop
61if is_service_enabled net-6wind; then 68if is_service_enabled net-6wind; then
62 source $NET_6WIND_DIR/devstack/libs/fast-path 69 source $NET_6WIND_DIR/devstack/libs/fast-path
@@ -71,6 +78,7 @@ if is_service_enabled net-6wind; then
71 elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then 78 elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
72 if is_service_enabled nova; then 79 if is_service_enabled nova; then
73 create_nova_rootwrap 80 create_nova_rootwrap
81 nova_enable_monkey_patch
74 fi 82 fi
75 if is_service_enabled neutron; then 83 if is_service_enabled neutron; then
76 configure_ml2_for_fast_path 84 configure_ml2_for_fast_path
diff --git a/etc/nova/rootwrap.d/6wind.filters b/etc/nova/rootwrap.d/6wind.filters
index 6940684..4562794 100644
--- a/etc/nova/rootwrap.d/6wind.filters
+++ b/etc/nova/rootwrap.d/6wind.filters
@@ -1,3 +1,4 @@
1[Filters] 1[Filters]
2vif-ovs-fp-plug: CommandFilter, /usr/local/bin/vif-ovs-fp-plug, root
2fp-shmem-ports: CommandFilter, /usr/local/bin/fp-shmem-ports, root 3fp-shmem-ports: CommandFilter, /usr/local/bin/fp-shmem-ports, root
3fp-cli: CommandFilter, /usr/local/bin/fp-cli, root 4fp-cli: CommandFilter, /usr/local/bin/fp-cli, root
diff --git a/networking_6wind/common/constants.py b/networking_6wind/common/constants.py
index ec0a8c5..39e6dc7 100644
--- a/networking_6wind/common/constants.py
+++ b/networking_6wind/common/constants.py
@@ -13,9 +13,6 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16# constants for 'vif_details'
17VIF_PLUGIN_SCRIPT = 'vif_plugin_script'
18
19# constants for the 'vif_type' field 16# constants for the 'vif_type' field
20VIF_TYPE_VHOSTUSER = 'vhostuser' 17VIF_TYPE_VHOSTUSER = 'vhostuser'
21 18
diff --git a/networking_6wind/ml2_drivers/mech_ovs_fp.py b/networking_6wind/ml2_drivers/mech_ovs_fp.py
index c60e418..683a409 100644
--- a/networking_6wind/ml2_drivers/mech_ovs_fp.py
+++ b/networking_6wind/ml2_drivers/mech_ovs_fp.py
@@ -41,7 +41,7 @@ class OVSFPMechanismDriver(mech_openvswitch.OpenvswitchMechanismDriver):
41 sg_enabled = securitygroups_rpc.is_firewall_enabled() 41 sg_enabled = securitygroups_rpc.is_firewall_enabled()
42 vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled, 42 vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
43 portbindings.OVS_HYBRID_PLUG: sg_enabled, 43 portbindings.OVS_HYBRID_PLUG: sg_enabled,
44 constants.VIF_PLUGIN_SCRIPT: "vif-ovs-fp-plug" 44 portbindings.VHOST_USER_OVS_PLUG: True,
45 } 45 }
46 46
47 SimpleAgentMechanismDriverBase.__init__(self, 47 SimpleAgentMechanismDriverBase.__init__(self,
diff --git a/networking_6wind/monkey_patch/__init__.py b/networking_6wind/monkey_patch/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/networking_6wind/monkey_patch/__init__.py
diff --git a/networking_6wind/monkey_patch/vif.py b/networking_6wind/monkey_patch/vif.py
new file mode 100644
index 0000000..42077d2
--- /dev/null
+++ b/networking_6wind/monkey_patch/vif.py
@@ -0,0 +1,82 @@
1# Copyright 2015 6WIND S.A.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15"""
16Extented support of vif drivers
17"""
18
19from nova.network import model
20from nova import utils
21from oslo_log import log as logging
22
23LOG = logging.getLogger(__name__)
24
25_plug_vhostuser = None
26_unplug_vhostuser = None
27
28
29def decorator(name, function):
30 """This function must be used with the monkey_patch_modules option in nova.conf
31
32 Example:
33 monkey_patch=true
34 monkey_patch_modules=nova.virt.libvirt.vif:\
35 openstack_dpdk_vnic.kilo.nova.virt.libvirt.vif.decorator
36 """
37 global _plug_vhostuser, _unplug_vhostuser
38
39 if name == 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver.plug_vhostuser':
40 _plug_vhostuser = function
41 return plug_vhostuser
42 elif name == (
43 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver.unplug_vhostuser'):
44 _unplug_vhostuser = function
45 return unplug_vhostuser
46 else:
47 return function
48
49
50# The following functions are used as monkey patches on the code defined in
51# nova/virt/libvirt/vif.py
52
53def plug_vhostuser(self, instance, vif):
54 ovs_fp_plug = vif['details'].get(model.VIF_DETAILS_VHOSTUSER_OVS_PLUG,
55 False)
56 if ovs_fp_plug:
57 iface_id = self.get_ovs_interfaceid(vif)
58 port_name = vif['details'][model.VIF_DETAILS_VHOSTUSER_SOCKET]
59 dev = self.get_vif_devname(vif)
60 bridge_name = self.get_bridge_name(vif)
61
62 utils.execute('vif-ovs-fp-plug', 'plug', vif['id'], vif['address'],
63 instance.uuid, port_name,
64 dev, iface_id, bridge_name,
65 vif.is_hybrid_plug_enabled(),
66 run_as_root=True)
67
68
69def unplug_vhostuser(self, instance, vif):
70 ovs_fp_plug = vif['details'].get(model.VIF_DETAILS_VHOSTUSER_OVS_PLUG,
71 False)
72 if ovs_fp_plug:
73 iface_id = self.get_ovs_interfaceid(vif)
74 port_name = vif['details'][model.VIF_DETAILS_VHOSTUSER_SOCKET]
75 dev = self.get_vif_devname(vif)
76 bridge_name = self.get_bridge_name(vif)
77
78 utils.execute('vif-ovs-fp-plug', 'unplug', vif['id'], vif['address'],
79 instance.uuid, port_name,
80 dev, iface_id, bridge_name,
81 vif.is_hybrid_plug_enabled(),
82 run_as_root=True)
diff --git a/networking_6wind/plug_scripts/vif_ovs_fp_plug.py b/networking_6wind/plug_scripts/vif_ovs_fp_plug.py
index 5dda9c6..4fb8ee4 100644
--- a/networking_6wind/plug_scripts/vif_ovs_fp_plug.py
+++ b/networking_6wind/plug_scripts/vif_ovs_fp_plug.py
@@ -17,7 +17,6 @@
17from __future__ import print_function 17from __future__ import print_function
18 18
19import argparse 19import argparse
20import os
21import sys 20import sys
22 21
23from oslo_concurrency import processutils 22from oslo_concurrency import processutils
@@ -149,36 +148,37 @@ def parse_args():
149 parser.add_argument('action', metavar='ACTION', 148 parser.add_argument('action', metavar='ACTION',
150 help='Action to perform with vif on the ovs bridge', 149 help='Action to perform with vif on the ovs bridge',
151 choices=['plug', 'unplug']) 150 choices=['plug', 'unplug'])
151 parser.add_argument('vif_id', metavar='VIF_ID',
152 help='Virtual interface id')
153 parser.add_argument('vif_address', metavar='VIF_ADDRESS',
154 help='Virtual interface address')
155 parser.add_argument('vif_instance_id', metavar='VIF_INSTANCE_ID',
156 help='Virtual interface instance id')
157 parser.add_argument('vif_vhostuser_socket',
158 metavar='VIF_DETAILS_VHOSTUSER_SOCKET',
159 help='Virtual interface vhostuser socket')
160 parser.add_argument('devname', metavar='VIF_DEVNAME',
161 help='Devname')
162 parser.add_argument('ovs_interfaceid', metavar='VIF_INTERFACE_ID',
163 help='Virtual interface id')
164 parser.add_argument('bridge_name', metavar='VIF_BRIDGE_NAME',
165 help='Virtual interface bridge name')
166 parser.add_argument('ovs_hybrid_plug',
167 metavar='VIF_DETAILS_OVS_HYBRID_PLUG',
168 help='OVS hybrid plug')
169
152 args = parser.parse_args() 170 args = parser.parse_args()
153 171
154 args.vif = {} 172 args.vif = {}
155 173 args.vif['id'] = args.vif_id
156 # mandatory environnement variable 174 args.vif['address'] = args.vif_address
157 args.vif['id'] = os.getenv('VIF_ID') 175 args.vif['instance_id'] = args.vif_instance_id
158 args.vif['address'] = os.getenv('VIF_ADDRESS') 176 args.vif['vhostuser_socket'] = args.vif_vhostuser_socket
159 args.vif['instance_id'] = os.getenv('VIF_INSTANCE_ID') 177 args.vif['devname'] = args.devname
160 args.vif['vhostuser_socket'] = os.getenv('VIF_DETAILS_VHOSTUSER_SOCKET') 178 args.vif['ovs_interfaceid'] = args.ovs_interfaceid
161 179 args.vif['bridge_name'] = args.bridge_name
162 if args.vif['id'] is None: 180 args.vif['port_filter'] = 'false'
163 parser.error('missing VIF_ID environment variable') 181 args.vif['ovs_hybrid_plug'] = args.ovs_hybrid_plug
164 if args.vif['address'] is None:
165 parser.error('missing VIF_ADDRESS environment variable')
166 if args.vif['instance_id'] is None:
167 parser.error('missing VIF_INSTANCE_ID environment variable')
168 if args.vif['vhostuser_socket'] is None:
169 parser.error('missing VIF_DETAILS_VHOSTUSER_SOCKET'
170 ' environment variable')
171
172 # optionnal environnement variable
173 default_devname = "tap" + args.vif['id'][:utils.NIC_NAME_LEN]
174 args.vif['devname'] = os.getenv('VIF_DEVNAME', default_devname)
175 args.vif['ovs_interfaceid'] = os.getenv('VIF_OVS_INTERFACEID',
176 args.vif['id'])
177 # TOFIX: bridge_name should be given by VIF_NETWORK_BRIDGE
178 args.vif['bridge_name'] = 'br-int'
179 args.vif['port_filter'] = os.getenv('VIF_DETAILS_PORTS_FILTER', 'false')
180 args.vif['ovs_hybrid_plug'] = os.getenv('VIF_DETAILS_OVS_HYBRID_PLUG',
181 'false')
182 182
183 return args 183 return args
184 184
diff --git a/networking_6wind/tests/unit/ml2_drivers/test_mech_ovs_fp.py b/networking_6wind/tests/unit/ml2_drivers/test_mech_ovs_fp.py
index 6d339bb..399a391 100644
--- a/networking_6wind/tests/unit/ml2_drivers/test_mech_ovs_fp.py
+++ b/networking_6wind/tests/unit/ml2_drivers/test_mech_ovs_fp.py
@@ -29,7 +29,7 @@ class OVSFPMechanismBaseTestCase(test_ovs.OpenvswitchMechanismBaseTestCase):
29 VIF_TYPE = constants.VIF_TYPE_VHOSTUSER 29 VIF_TYPE = constants.VIF_TYPE_VHOSTUSER
30 VIF_DETAILS = {portbindings.CAP_PORT_FILTER: True, 30 VIF_DETAILS = {portbindings.CAP_PORT_FILTER: True,
31 portbindings.OVS_HYBRID_PLUG: True, 31 portbindings.OVS_HYBRID_PLUG: True,
32 constants.VIF_PLUGIN_SCRIPT: "vif-ovs-fp-plug", 32 portbindings.VHOST_USER_OVS_PLUG: True,
33 constants.VIF_VHOSTUSER_SOCKET: get_vif_vhostuser_socket( 33 constants.VIF_VHOSTUSER_SOCKET: get_vif_vhostuser_socket(
34 base.PORT_ID)} 34 base.PORT_ID)}
35 35
@@ -43,7 +43,7 @@ class OVSFPMechanismSGDisabledBaseTestCase(
43 OVSFPMechanismBaseTestCase): 43 OVSFPMechanismBaseTestCase):
44 VIF_DETAILS = {portbindings.CAP_PORT_FILTER: False, 44 VIF_DETAILS = {portbindings.CAP_PORT_FILTER: False,
45 portbindings.OVS_HYBRID_PLUG: False, 45 portbindings.OVS_HYBRID_PLUG: False,
46 constants.VIF_PLUGIN_SCRIPT: "vif-ovs-fp-plug", 46 portbindings.VHOST_USER_OVS_PLUG: True,
47 constants.VIF_VHOSTUSER_SOCKET: get_vif_vhostuser_socket( 47 constants.VIF_VHOSTUSER_SOCKET: get_vif_vhostuser_socket(
48 base.PORT_ID)} 48 base.PORT_ID)}
49 49