Merge "libvirt: convert over to use os-vif for Linux Bridge & OVS"
This commit is contained in:
commit
d93913fe7f
@ -60,15 +60,6 @@ class DesignerTestCase(test.NoDBTestCase):
|
||||
self.assertEqual('fake-tap', conf.target_dev)
|
||||
self.assertEqual('', conf.script)
|
||||
|
||||
def test_set_vif_host_backend_ovs_config(self):
|
||||
conf = config.LibvirtConfigGuestInterface()
|
||||
designer.set_vif_host_backend_ovs_config(conf, 'fake-bridge',
|
||||
'fake-interface', 'fake-tap')
|
||||
self.assertEqual('bridge', conf.net_type)
|
||||
self.assertEqual('fake-bridge', conf.source_dev)
|
||||
self.assertEqual('openvswitch', conf.vporttype)
|
||||
self.assertEqual('fake-tap', conf.target_dev)
|
||||
|
||||
def test_set_vif_host_backend_802qbg_config(self):
|
||||
conf = config.LibvirtConfigGuestInterface()
|
||||
designer.set_vif_host_backend_802qbg_config(conf, 'fake-devname',
|
||||
|
@ -6854,7 +6854,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
||||
|
||||
filterref = './devices/interface/filterref'
|
||||
vif = network_info[0]
|
||||
nic_id = vif['address'].replace(':', '')
|
||||
nic_id = vif['address'].lower().replace(':', '')
|
||||
fw = firewall.NWFilterFirewall(drvr)
|
||||
instance_filter_name = fw._instance_filter_name(instance_ref,
|
||||
nic_id)
|
||||
|
@ -17,6 +17,9 @@ import os
|
||||
import fixtures
|
||||
from lxml import etree
|
||||
import mock
|
||||
import os_vif
|
||||
from os_vif import exception as osv_exception
|
||||
from os_vif import objects as osv_objects
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_config import cfg
|
||||
import six
|
||||
@ -27,6 +30,7 @@ from nova.network import model as network_model
|
||||
from nova import objects
|
||||
from nova.pci import utils as pci_utils
|
||||
from nova import test
|
||||
from nova.tests.unit import matchers
|
||||
from nova.tests.unit.virt import fakelibosinfo
|
||||
from nova import utils
|
||||
from nova.virt.libvirt import config as vconfig
|
||||
@ -384,6 +388,49 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
'quota:vif_outbound_burst': '30'
|
||||
}
|
||||
|
||||
os_vif_network = osv_objects.network.Network(
|
||||
id="b82c1929-051e-481d-8110-4669916c7915",
|
||||
label="Demo Net",
|
||||
subnets=osv_objects.subnet.SubnetList(
|
||||
objects=[]))
|
||||
|
||||
os_vif_bridge = osv_objects.vif.VIFBridge(
|
||||
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
|
||||
address="22:52:25:62:e2:aa",
|
||||
plugin="linux_bridge",
|
||||
vif_name="nicdc065497-3c",
|
||||
bridge_name="br100",
|
||||
has_traffic_filtering=False,
|
||||
network=os_vif_network)
|
||||
|
||||
os_vif_ovs_prof = osv_objects.vif.VIFPortProfileOpenVSwitch(
|
||||
interface_id="07bd6cea-fb37-4594-b769-90fc51854ee9",
|
||||
profile_id="fishfood")
|
||||
|
||||
os_vif_ovs = osv_objects.vif.VIFOpenVSwitch(
|
||||
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
|
||||
address="22:52:25:62:e2:aa",
|
||||
unplugin="linux_bridge",
|
||||
vif_name="nicdc065497-3c",
|
||||
bridge_name="br0",
|
||||
port_profile=os_vif_ovs_prof,
|
||||
network=os_vif_network)
|
||||
|
||||
os_vif_ovs_hybrid = osv_objects.vif.VIFBridge(
|
||||
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
|
||||
address="22:52:25:62:e2:aa",
|
||||
unplugin="linux_bridge",
|
||||
vif_name="nicdc065497-3c",
|
||||
bridge_name="br0",
|
||||
port_profile=os_vif_ovs_prof,
|
||||
has_traffic_filtering=False,
|
||||
network=os_vif_network)
|
||||
|
||||
os_vif_inst_info = osv_objects.instance_info.InstanceInfo(
|
||||
uuid="d5b1090c-9e00-4fa4-9504-4b1494857970",
|
||||
name="instance-000004da",
|
||||
project_id="2f37d7f6-e51a-4a1f-8b6e-b0917ffc8390")
|
||||
|
||||
def setUp(self):
|
||||
super(LibvirtVifTestCase, self).setUp()
|
||||
self.flags(allow_same_net_traffic=True)
|
||||
@ -455,6 +502,9 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
pci_slot_want = vif['profile']['pci_slot']
|
||||
self.assertEqual(pci_slot, pci_slot_want)
|
||||
|
||||
def _assertXmlEqual(self, expectedXmlstr, actualXmlstr):
|
||||
self.assertThat(actualXmlstr, matchers.XMLMatches(expectedXmlstr))
|
||||
|
||||
def _get_conf(self):
|
||||
conf = vconfig.LibvirtConfigGuest()
|
||||
conf.virt_type = "qemu"
|
||||
@ -616,7 +666,7 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
image_meta = {'properties': {'os_name': 'fedora22'}}
|
||||
image_meta = objects.ImageMeta.from_dict(image_meta)
|
||||
d.get_base_config(None, self.vif_bridge, image_meta,
|
||||
d.get_base_config(None, 'ca:fe:de:ad:be:ef', image_meta,
|
||||
None, 'kvm')
|
||||
mock_set.assert_called_once_with(mock.ANY, 'ca:fe:de:ad:be:ef',
|
||||
'virtio', None, None)
|
||||
@ -719,85 +769,6 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
delete.side_effect = processutils.ProcessExecutionError
|
||||
d.unplug(self.instance, self.vif_ivs)
|
||||
|
||||
def _test_plug_ovs_hybrid(self, ipv6_exists):
|
||||
calls = {
|
||||
'device_exists': [mock.call('qbrvif-xxx-yyy'),
|
||||
mock.call('qvovif-xxx-yyy')],
|
||||
'_create_veth_pair': [mock.call('qvbvif-xxx-yyy',
|
||||
'qvovif-xxx-yyy', 1000)],
|
||||
'execute': [mock.call('brctl', 'addbr', 'qbrvif-xxx-yyy',
|
||||
run_as_root=True),
|
||||
mock.call('brctl', 'setfd', 'qbrvif-xxx-yyy', 0,
|
||||
run_as_root=True),
|
||||
mock.call('brctl', 'stp', 'qbrvif-xxx-yyy', 'off',
|
||||
run_as_root=True),
|
||||
mock.call('tee', ('/sys/class/net/qbrvif-xxx-yyy'
|
||||
'/bridge/multicast_snooping'),
|
||||
process_input='0', run_as_root=True,
|
||||
check_exit_code=[0, 1])],
|
||||
'create_ovs_vif_port': [mock.call(
|
||||
'br0', 'qvovif-xxx-yyy', 'aaa-bbb-ccc',
|
||||
'ca:fe:de:ad:be:ef',
|
||||
'f0000000-0000-0000-0000-000000000001',
|
||||
1000)]
|
||||
}
|
||||
# The disable_ipv6 call needs to be added in the middle, if required
|
||||
if ipv6_exists:
|
||||
calls['execute'].extend([
|
||||
mock.call('tee', ('/proc/sys/net/ipv6/conf'
|
||||
'/qbrvif-xxx-yyy/disable_ipv6'),
|
||||
process_input='1', run_as_root=True,
|
||||
check_exit_code=[0, 1])])
|
||||
calls['execute'].extend([
|
||||
mock.call('ip', 'link', 'set', 'qbrvif-xxx-yyy', 'up',
|
||||
run_as_root=True),
|
||||
mock.call('brctl', 'addif', 'qbrvif-xxx-yyy',
|
||||
'qvbvif-xxx-yyy', run_as_root=True)])
|
||||
with test.nested(
|
||||
mock.patch.object(linux_net, 'device_exists',
|
||||
return_value=False),
|
||||
mock.patch.object(utils, 'execute'),
|
||||
mock.patch.object(linux_net, '_create_veth_pair'),
|
||||
mock.patch.object(linux_net, 'create_ovs_vif_port'),
|
||||
mock.patch.object(os.path, 'exists', return_value=ipv6_exists)
|
||||
) as (device_exists, execute, _create_veth_pair, create_ovs_vif_port,
|
||||
path_exists):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.plug(self.instance, self.vif_ovs)
|
||||
device_exists.assert_has_calls(calls['device_exists'])
|
||||
_create_veth_pair.assert_has_calls(calls['_create_veth_pair'])
|
||||
execute.assert_has_calls(calls['execute'])
|
||||
create_ovs_vif_port.assert_has_calls(calls['create_ovs_vif_port'])
|
||||
|
||||
def test_plug_ovs_hybrid_ipv6(self):
|
||||
self._test_plug_ovs_hybrid(ipv6_exists=True)
|
||||
|
||||
def test_plug_ovs_hybrid_no_ipv6(self):
|
||||
self._test_plug_ovs_hybrid(ipv6_exists=False)
|
||||
|
||||
def test_unplug_ovs_hybrid(self):
|
||||
calls = {
|
||||
'device_exists': [mock.call('qbrvif-xxx-yyy')],
|
||||
'execute': [mock.call('brctl', 'delif', 'qbrvif-xxx-yyy',
|
||||
'qvbvif-xxx-yyy', run_as_root=True),
|
||||
mock.call('ip', 'link', 'set',
|
||||
'qbrvif-xxx-yyy', 'down', run_as_root=True),
|
||||
mock.call('brctl', 'delbr',
|
||||
'qbrvif-xxx-yyy', run_as_root=True)],
|
||||
'delete_ovs_vif_port': [mock.call('br0', 'qvovif-xxx-yyy')]
|
||||
}
|
||||
with test.nested(
|
||||
mock.patch.object(linux_net, 'device_exists',
|
||||
return_value=True),
|
||||
mock.patch.object(utils, 'execute'),
|
||||
mock.patch.object(linux_net, 'delete_ovs_vif_port')
|
||||
) as (device_exists, execute, delete_ovs_vif_port):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.unplug(self.instance, self.vif_ovs)
|
||||
device_exists.assert_has_calls(calls['device_exists'])
|
||||
execute.assert_has_calls(calls['execute'])
|
||||
delete_ovs_vif_port.assert_has_calls(calls['delete_ovs_vif_port'])
|
||||
|
||||
@mock.patch.object(utils, 'execute')
|
||||
@mock.patch.object(pci_utils, 'get_ifname_by_pci_address')
|
||||
@mock.patch.object(pci_utils, 'get_vf_num_by_pci_address', return_value=1)
|
||||
@ -839,21 +810,6 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
self._test_hw_veb_op(d.unplug, 0)
|
||||
|
||||
def test_unplug_ovs_hybrid_bridge_does_not_exist(self):
|
||||
calls = {
|
||||
'device_exists': [mock.call('qbrvif-xxx-yyy')],
|
||||
'delete_ovs_vif_port': [mock.call('br0', 'qvovif-xxx-yyy')]
|
||||
}
|
||||
with test.nested(
|
||||
mock.patch.object(linux_net, 'device_exists',
|
||||
return_value=False),
|
||||
mock.patch.object(linux_net, 'delete_ovs_vif_port')
|
||||
) as (device_exists, delete_ovs_vif_port):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.unplug(self.instance, self.vif_ovs)
|
||||
device_exists.assert_has_calls(calls['device_exists'])
|
||||
delete_ovs_vif_port.assert_has_calls(calls['delete_ovs_vif_port'])
|
||||
|
||||
def test_plug_ivs_hybrid(self):
|
||||
calls = {
|
||||
'device_exists': [mock.call('qbrvif-xxx-yyy'),
|
||||
@ -1482,3 +1438,163 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
execute.assert_has_calls(calls['execute'])
|
||||
delete_ovs_vif_port.assert_has_calls(calls['delete_ovs_vif_port'])
|
||||
delete_fp_dev.assert_has_calls(calls['delete_fp_dev'])
|
||||
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
|
||||
@mock.patch.object(os_vif, "plug")
|
||||
def _test_osvif_plug(self, fail, mock_plug,
|
||||
mock_convert_vif, mock_convert_inst):
|
||||
mock_convert_vif.return_value = self.os_vif_bridge
|
||||
mock_convert_inst.return_value = self.os_vif_inst_info
|
||||
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
if fail:
|
||||
mock_plug.side_effect = osv_exception.ExceptionBase("Wibble")
|
||||
self.assertRaises(exception.NovaException,
|
||||
d.plug,
|
||||
self.instance, self.vif_bridge)
|
||||
else:
|
||||
d.plug(self.instance, self.vif_bridge)
|
||||
|
||||
mock_plug.assert_called_once_with(self.os_vif_bridge,
|
||||
self.os_vif_inst_info)
|
||||
|
||||
def test_osvif_plug_normal(self):
|
||||
self._test_osvif_plug(False)
|
||||
|
||||
def test_osvif_plug_fail(self):
|
||||
self._test_osvif_plug(True)
|
||||
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
|
||||
@mock.patch.object(os_vif, "unplug")
|
||||
def _test_osvif_unplug(self, fail, mock_unplug,
|
||||
mock_convert_vif, mock_convert_inst):
|
||||
mock_convert_vif.return_value = self.os_vif_bridge
|
||||
mock_convert_inst.return_value = self.os_vif_inst_info
|
||||
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
if fail:
|
||||
mock_unplug.side_effect = osv_exception.ExceptionBase("Wibble")
|
||||
self.assertRaises(exception.NovaException,
|
||||
d.unplug,
|
||||
self.instance, self.vif_bridge)
|
||||
else:
|
||||
d.unplug(self.instance, self.vif_bridge)
|
||||
|
||||
mock_unplug.assert_called_once_with(self.os_vif_bridge,
|
||||
self.os_vif_inst_info)
|
||||
|
||||
def test_osvif_unplug_normal(self):
|
||||
self._test_osvif_unplug(False)
|
||||
|
||||
def test_osvif_unplug_fail(self):
|
||||
self._test_osvif_unplug(True)
|
||||
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
|
||||
def test_config_os_vif_bridge(self, mock_convert_vif, mock_convert_inst):
|
||||
mock_convert_vif.return_value = self.os_vif_bridge
|
||||
mock_convert_inst.return_value = self.os_vif_inst_info
|
||||
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
hostimpl = host.Host("qemu:///system")
|
||||
flavor = objects.Flavor(name='m1.small')
|
||||
image_meta = objects.ImageMeta.from_dict({})
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
cfg = d.get_config(self.instance, self.vif_bridge,
|
||||
image_meta, flavor,
|
||||
CONF.libvirt.virt_type,
|
||||
hostimpl)
|
||||
|
||||
self._assertXmlEqual("""
|
||||
<interface type="bridge">
|
||||
<mac address="22:52:25:62:e2:aa"/>
|
||||
<model type="virtio"/>
|
||||
<source bridge="br100"/>
|
||||
<target dev="nicdc065497-3c"/>
|
||||
<filterref
|
||||
filter="nova-instance-instance-00000001-22522562e2aa"/>
|
||||
</interface>""", cfg.to_xml())
|
||||
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
|
||||
def test_config_os_vif_bridge_nofw(self, mock_convert_vif,
|
||||
mock_convert_inst):
|
||||
self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver")
|
||||
|
||||
mock_convert_vif.return_value = self.os_vif_bridge
|
||||
mock_convert_inst.return_value = self.os_vif_inst_info
|
||||
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
hostimpl = host.Host("qemu:///system")
|
||||
flavor = objects.Flavor(name='m1.small')
|
||||
image_meta = objects.ImageMeta.from_dict({})
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
cfg = d.get_config(self.instance, self.vif_bridge,
|
||||
image_meta, flavor,
|
||||
CONF.libvirt.virt_type,
|
||||
hostimpl)
|
||||
|
||||
self._assertXmlEqual("""
|
||||
<interface type="bridge">
|
||||
<mac address="22:52:25:62:e2:aa"/>
|
||||
<model type="virtio"/>
|
||||
<source bridge="br100"/>
|
||||
<target dev="nicdc065497-3c"/>
|
||||
</interface>""", cfg.to_xml())
|
||||
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
|
||||
def test_config_os_vif_ovs(self, mock_convert_vif, mock_convert_inst):
|
||||
mock_convert_vif.return_value = self.os_vif_ovs
|
||||
mock_convert_inst.return_value = self.os_vif_inst_info
|
||||
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
hostimpl = host.Host("qemu:///system")
|
||||
flavor = objects.Flavor(name='m1.small')
|
||||
image_meta = objects.ImageMeta.from_dict({})
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
cfg = d.get_config(self.instance, self.vif_ovs,
|
||||
image_meta, flavor,
|
||||
CONF.libvirt.virt_type,
|
||||
hostimpl)
|
||||
|
||||
self._assertXmlEqual("""
|
||||
<interface type="bridge">
|
||||
<mac address="22:52:25:62:e2:aa"/>
|
||||
<model type="virtio"/>
|
||||
<source bridge="br0"/>
|
||||
<target dev="nicdc065497-3c"/>
|
||||
<virtualport type="openvswitch">
|
||||
<parameters
|
||||
interfaceid="07bd6cea-fb37-4594-b769-90fc51854ee9"/>
|
||||
</virtualport>
|
||||
</interface>""", cfg.to_xml())
|
||||
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
|
||||
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
|
||||
def test_config_os_vif_ovs_hybrid(self, mock_convert_vif,
|
||||
mock_convert_inst):
|
||||
mock_convert_vif.return_value = self.os_vif_ovs_hybrid
|
||||
mock_convert_inst.return_value = self.os_vif_inst_info
|
||||
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
hostimpl = host.Host("qemu:///system")
|
||||
flavor = objects.Flavor(name='m1.small')
|
||||
image_meta = objects.ImageMeta.from_dict({})
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
cfg = d.get_config(self.instance, self.vif_ovs,
|
||||
image_meta, flavor,
|
||||
CONF.libvirt.virt_type,
|
||||
hostimpl)
|
||||
|
||||
self._assertXmlEqual("""
|
||||
<interface type="bridge">
|
||||
<mac address="22:52:25:62:e2:aa"/>
|
||||
<model type="virtio"/>
|
||||
<source bridge="br0"/>
|
||||
<target dev="nicdc065497-3c"/>
|
||||
<filterref
|
||||
filter="nova-instance-instance-00000001-22522562e2aa"/>
|
||||
</interface>""", cfg.to_xml())
|
||||
|
@ -61,19 +61,6 @@ def set_vif_host_backend_ethernet_config(conf, tapname):
|
||||
conf.script = ""
|
||||
|
||||
|
||||
def set_vif_host_backend_ovs_config(conf, brname, interfaceid, tapname=None):
|
||||
"""Populate a LibvirtConfigGuestInterface instance
|
||||
with host backend details for an OpenVSwitch bridge.
|
||||
"""
|
||||
|
||||
conf.net_type = "bridge"
|
||||
conf.source_dev = brname
|
||||
conf.vporttype = "openvswitch"
|
||||
conf.add_vport_param("interfaceid", interfaceid)
|
||||
if tapname:
|
||||
conf.target_dev = tapname
|
||||
|
||||
|
||||
def set_vif_host_backend_802qbg_config(conf, devname, managerid,
|
||||
typeid, typeidversion,
|
||||
instanceid, tapname=None):
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Copyright (C) 2011 Nicira, Inc
|
||||
# Copyright 2011 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
@ -20,6 +21,8 @@
|
||||
import copy
|
||||
|
||||
import os
|
||||
import os_vif
|
||||
from os_vif import exception as osv_exception
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_log import log as logging
|
||||
|
||||
@ -29,6 +32,7 @@ from nova.i18n import _
|
||||
from nova.i18n import _LE
|
||||
from nova.network import linux_net
|
||||
from nova.network import model as network_model
|
||||
from nova.network import os_vif_util
|
||||
from nova import objects
|
||||
from nova import utils
|
||||
from nova.virt.libvirt import config as vconfig
|
||||
@ -90,7 +94,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
devname = self.get_vif_devname(vif)
|
||||
return prefix + devname[3:]
|
||||
|
||||
def get_base_config(self, instance, vif, image_meta,
|
||||
def get_base_config(self, instance, mac, image_meta,
|
||||
inst_type, virt_type):
|
||||
conf = vconfig.LibvirtConfigGuestInterface()
|
||||
# Default to letting libvirt / the hypervisor choose the model
|
||||
@ -127,7 +131,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
driver = vhost_drv or driver
|
||||
|
||||
designer.set_vif_guest_frontend_config(
|
||||
conf, vif['address'], model, driver, vhost_queues)
|
||||
conf, mac, model, driver, vhost_queues)
|
||||
|
||||
return conf
|
||||
|
||||
@ -186,17 +190,28 @@ class LibvirtGenericVIFDriver(object):
|
||||
return (("qvb%s" % iface_id)[:network_model.NIC_NAME_LEN],
|
||||
("qvo%s" % iface_id)[:network_model.NIC_NAME_LEN])
|
||||
|
||||
@staticmethod
|
||||
def is_no_op_firewall():
|
||||
return CONF.firewall_driver == "nova.virt.firewall.NoopFirewallDriver"
|
||||
|
||||
def get_firewall_required(self, vif):
|
||||
if vif.is_neutron_filtering_enabled():
|
||||
return False
|
||||
if CONF.firewall_driver != "nova.virt.firewall.NoopFirewallDriver":
|
||||
return True
|
||||
return False
|
||||
if self.is_no_op_firewall():
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_firewall_required_os_vif(self, vif):
|
||||
if vif.has_traffic_filtering:
|
||||
return False
|
||||
if self.is_no_op_firewall():
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_config_bridge(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
"""Get VIF configurations for bridge type."""
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
designer.set_vif_host_backend_bridge_config(
|
||||
@ -211,42 +226,6 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
return conf
|
||||
|
||||
def get_config_ovs_bridge(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
designer.set_vif_host_backend_ovs_config(
|
||||
conf, self.get_bridge_name(vif),
|
||||
self.get_ovs_interfaceid(vif),
|
||||
self.get_vif_devname(vif))
|
||||
|
||||
designer.set_vif_bandwidth_config(conf, inst_type)
|
||||
|
||||
return conf
|
||||
|
||||
def get_config_ovs_hybrid(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
newvif = copy.deepcopy(vif)
|
||||
newvif['network']['bridge'] = self.get_br_name(vif['id'])
|
||||
return self.get_config_bridge(instance, newvif, image_meta,
|
||||
inst_type, virt_type, host)
|
||||
|
||||
def get_config_ovs(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
if self.get_firewall_required(vif) or vif.is_hybrid_plug_enabled():
|
||||
return self.get_config_ovs_hybrid(instance, vif,
|
||||
image_meta,
|
||||
inst_type,
|
||||
virt_type,
|
||||
host)
|
||||
else:
|
||||
return self.get_config_ovs_bridge(instance, vif,
|
||||
image_meta,
|
||||
inst_type,
|
||||
virt_type,
|
||||
host)
|
||||
|
||||
def get_config_ivs_hybrid(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
newvif = copy.deepcopy(vif)
|
||||
@ -261,7 +240,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
def get_config_ivs_ethernet(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance,
|
||||
vif,
|
||||
vif['address'],
|
||||
image_meta,
|
||||
inst_type,
|
||||
virt_type)
|
||||
@ -288,7 +267,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_802qbg(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
params = vif["qbg_params"]
|
||||
@ -305,7 +284,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_802qbh(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
profile = vif["profile"]
|
||||
@ -324,7 +303,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_hw_veb(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
profile = vif["profile"]
|
||||
@ -347,7 +326,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_macvtap(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
vif_details = vif['details']
|
||||
@ -378,7 +357,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_iovisor(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
dev = self.get_vif_devname(vif)
|
||||
@ -390,7 +369,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_midonet(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
dev = self.get_vif_devname(vif)
|
||||
@ -400,7 +379,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_tap(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
dev = self.get_vif_devname(vif)
|
||||
@ -420,7 +399,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_vhostuser(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
mode, sock_path = self._get_vhostuser_settings(vif)
|
||||
designer.set_vif_host_backend_vhostuser_config(conf, mode, sock_path)
|
||||
@ -439,7 +418,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
def get_config_vrouter(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
conf = self.get_base_config(instance, vif['address'], image_meta,
|
||||
inst_type, virt_type)
|
||||
dev = self.get_vif_devname(vif)
|
||||
designer.set_vif_host_backend_ethernet_config(conf, dev)
|
||||
@ -447,6 +426,69 @@ class LibvirtGenericVIFDriver(object):
|
||||
designer.set_vif_bandwidth_config(conf, inst_type)
|
||||
return conf
|
||||
|
||||
def _set_config_VIFBridge(self, instance, vif, conf):
|
||||
conf.net_type = "bridge"
|
||||
conf.source_dev = vif.bridge_name
|
||||
conf.target_dev = vif.vif_name
|
||||
|
||||
if self.get_firewall_required_os_vif(vif):
|
||||
mac_id = vif.address.replace(':', '')
|
||||
name = "nova-instance-" + instance.name + "-" + mac_id
|
||||
conf.filtername = name
|
||||
|
||||
def _set_config_VIFOpenVSwitch(self, instance, vif, conf):
|
||||
conf.net_type = "bridge"
|
||||
conf.source_dev = vif.bridge_name
|
||||
conf.target_dev = vif.vif_name
|
||||
self._set_config_VIFPortProfile(instance, vif, conf)
|
||||
|
||||
def _set_config_VIFPortProfileOpenVSwitch(self, profile, conf):
|
||||
conf.vporttype = "openvswitch"
|
||||
conf.add_vport_param("interfaceid",
|
||||
profile.interface_id)
|
||||
|
||||
def _set_config_VIFPortProfile(self, instance, vif, conf):
|
||||
# Set any port profile that may be required
|
||||
profilefunc = "_set_config_" + vif.port_profile.obj_name()
|
||||
func = getattr(self, profilefunc, None)
|
||||
if not func:
|
||||
raise exception.NovaException(
|
||||
"Unsupported VIF port profile type %(obj)s func %(func)s" %
|
||||
{'obj': vif.port_profile.obj_name(), 'func': profilefunc})
|
||||
|
||||
func(vif.port_profile, conf)
|
||||
|
||||
def _get_config_os_vif(self, instance, vif, image_meta, inst_type,
|
||||
virt_type, host):
|
||||
"""Get the domain config for a VIF
|
||||
|
||||
:param instance: nova.objects.Instance
|
||||
:param vif: os_vif.objects.vif.VIFBase subclass
|
||||
:param image_meta: nova.objects.ImageMeta
|
||||
:param inst_type: nova.objects.Flavor
|
||||
:param virt_type: virtualization type
|
||||
:param host: nova.virt.libvirt.host.Host
|
||||
|
||||
:returns: nova.virt.libvirt.config.LibvirtConfigGuestInterface
|
||||
"""
|
||||
|
||||
# Do the config that's common to all vif types
|
||||
conf = self.get_base_config(instance, vif.address, image_meta,
|
||||
inst_type, virt_type)
|
||||
|
||||
# Do the VIF type specific config
|
||||
viffunc = "_set_config_" + vif.obj_name()
|
||||
func = getattr(self, viffunc, None)
|
||||
if not func:
|
||||
raise exception.NovaException(
|
||||
"Unsupported VIF type %(obj)s func %(func)s" %
|
||||
{'obj': vif.obj_name(), 'func': viffunc})
|
||||
func(instance, vif, conf)
|
||||
|
||||
designer.set_vif_bandwidth_config(conf, inst_type)
|
||||
|
||||
return conf
|
||||
|
||||
def get_config(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
vif_type = vif['type']
|
||||
@ -460,6 +502,14 @@ class LibvirtGenericVIFDriver(object):
|
||||
raise exception.NovaException(
|
||||
_("vif_type parameter must be present "
|
||||
"for this vif_driver implementation"))
|
||||
|
||||
# Try os-vif codepath first
|
||||
vif_obj = os_vif_util.nova_to_osvif_vif(vif)
|
||||
if vif_obj is not None:
|
||||
return self._get_config_os_vif(instance, vif_obj, image_meta,
|
||||
inst_type, virt_type, host)
|
||||
|
||||
# Legacy non-os-vif codepath
|
||||
vif_slug = self._normalize_vif_type(vif_type)
|
||||
func = getattr(self, 'get_config_%s' % vif_slug, None)
|
||||
if not func:
|
||||
@ -468,35 +518,6 @@ class LibvirtGenericVIFDriver(object):
|
||||
return func(instance, vif, image_meta,
|
||||
inst_type, virt_type, host)
|
||||
|
||||
def plug_bridge(self, instance, vif):
|
||||
"""Ensure that the bridge exists, and add VIF to it."""
|
||||
network = vif['network']
|
||||
if (not network.get_meta('multi_host', False) and
|
||||
network.get_meta('should_create_bridge', False)):
|
||||
if network.get_meta('should_create_vlan', False):
|
||||
iface = CONF.vlan_interface or \
|
||||
network.get_meta('bridge_interface')
|
||||
LOG.debug('Ensuring vlan %(vlan)s and bridge %(bridge)s',
|
||||
{'vlan': network.get_meta('vlan'),
|
||||
'bridge': self.get_bridge_name(vif)},
|
||||
instance=instance)
|
||||
linux_net.LinuxBridgeInterfaceDriver.ensure_vlan_bridge(
|
||||
network.get_meta('vlan'),
|
||||
self.get_bridge_name(vif),
|
||||
iface)
|
||||
else:
|
||||
iface = CONF.flat_interface or \
|
||||
network.get_meta('bridge_interface')
|
||||
LOG.debug("Ensuring bridge %s",
|
||||
self.get_bridge_name(vif), instance=instance)
|
||||
linux_net.LinuxBridgeInterfaceDriver.ensure_bridge(
|
||||
self.get_bridge_name(vif),
|
||||
iface)
|
||||
|
||||
def plug_ovs_bridge(self, instance, vif):
|
||||
"""No manual plugging required."""
|
||||
pass
|
||||
|
||||
def _plug_bridge_with_port(self, instance, vif, port):
|
||||
iface_id = self.get_ovs_interfaceid(vif)
|
||||
br_name = self.get_br_name(vif['id'])
|
||||
@ -544,12 +565,6 @@ class LibvirtGenericVIFDriver(object):
|
||||
"""
|
||||
self._plug_bridge_with_port(instance, vif, port='ovs')
|
||||
|
||||
def plug_ovs(self, instance, vif):
|
||||
if self.get_firewall_required(vif) or vif.is_hybrid_plug_enabled():
|
||||
self.plug_ovs_hybrid(instance, vif)
|
||||
else:
|
||||
self.plug_ovs_bridge(instance, vif)
|
||||
|
||||
def plug_ivs_ethernet(self, instance, vif):
|
||||
iface_id = self.get_ovs_interfaceid(vif)
|
||||
dev = self.get_vif_devname(vif)
|
||||
@ -757,6 +772,16 @@ class LibvirtGenericVIFDriver(object):
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_LE("Failed while plugging vif"), instance=instance)
|
||||
|
||||
def _plug_os_vif(self, instance, vif):
|
||||
instance_info = os_vif_util.nova_to_osvif_instance(instance)
|
||||
|
||||
try:
|
||||
os_vif.plug(vif, instance_info)
|
||||
except osv_exception.ExceptionBase as ex:
|
||||
msg = (_("Failure running os_vif plugin plug method: %(ex)s")
|
||||
% {'ex': ex})
|
||||
raise exception.NovaException(msg)
|
||||
|
||||
def plug(self, instance, vif):
|
||||
vif_type = vif['type']
|
||||
|
||||
@ -769,6 +794,14 @@ class LibvirtGenericVIFDriver(object):
|
||||
raise exception.VirtualInterfacePlugException(
|
||||
_("vif_type parameter must be present "
|
||||
"for this vif_driver implementation"))
|
||||
|
||||
# Try os-vif codepath first
|
||||
vif_obj = os_vif_util.nova_to_osvif_vif(vif)
|
||||
if vif_obj is not None:
|
||||
self._plug_os_vif(instance, vif_obj)
|
||||
return
|
||||
|
||||
# Legacy non-os-vif codepath
|
||||
vif_slug = self._normalize_vif_type(vif_type)
|
||||
func = getattr(self, 'plug_%s' % vif_slug, None)
|
||||
if not func:
|
||||
@ -777,14 +810,6 @@ class LibvirtGenericVIFDriver(object):
|
||||
"vif_type=%s") % vif_type)
|
||||
func(instance, vif)
|
||||
|
||||
def unplug_bridge(self, instance, vif):
|
||||
"""No manual unplugging required."""
|
||||
pass
|
||||
|
||||
def unplug_ovs_bridge(self, instance, vif):
|
||||
"""No manual unplugging required."""
|
||||
pass
|
||||
|
||||
def unplug_ovs_hybrid(self, instance, vif):
|
||||
"""UnPlug using hybrid strategy
|
||||
|
||||
@ -809,12 +834,6 @@ class LibvirtGenericVIFDriver(object):
|
||||
LOG.exception(_LE("Failed while unplugging vif"),
|
||||
instance=instance)
|
||||
|
||||
def unplug_ovs(self, instance, vif):
|
||||
if self.get_firewall_required(vif) or vif.is_hybrid_plug_enabled():
|
||||
self.unplug_ovs_hybrid(instance, vif)
|
||||
else:
|
||||
self.unplug_ovs_bridge(instance, vif)
|
||||
|
||||
def unplug_ivs_ethernet(self, instance, vif):
|
||||
"""Unplug the VIF by deleting the port from the bridge."""
|
||||
try:
|
||||
@ -974,6 +993,16 @@ class LibvirtGenericVIFDriver(object):
|
||||
LOG.exception(
|
||||
_LE("Failed while unplugging vif"), instance=instance)
|
||||
|
||||
def _unplug_os_vif(self, instance, vif):
|
||||
instance_info = os_vif_util.nova_to_osvif_instance(instance)
|
||||
|
||||
try:
|
||||
os_vif.unplug(vif, instance_info)
|
||||
except osv_exception.ExceptionBase as ex:
|
||||
msg = (_("Failure running os_vif plugin unplug method: %(ex)s")
|
||||
% {'ex': ex})
|
||||
raise exception.NovaException(msg)
|
||||
|
||||
def unplug(self, instance, vif):
|
||||
vif_type = vif['type']
|
||||
|
||||
@ -986,6 +1015,14 @@ class LibvirtGenericVIFDriver(object):
|
||||
raise exception.NovaException(
|
||||
_("vif_type parameter must be present "
|
||||
"for this vif_driver implementation"))
|
||||
|
||||
# Try os-vif codepath first
|
||||
vif_obj = os_vif_util.nova_to_osvif_vif(vif)
|
||||
if vif_obj is not None:
|
||||
self._unplug_os_vif(instance, vif_obj)
|
||||
return
|
||||
|
||||
# Legacy non-os-vif codepath
|
||||
vif_slug = self._normalize_vif_type(vif_type)
|
||||
func = getattr(self, 'unplug_%s' % vif_slug, None)
|
||||
if not func:
|
||||
|
@ -0,0 +1,35 @@
|
||||
---
|
||||
features:
|
||||
- The Libvirt driver now uses os-vif plugins for
|
||||
handling plug/unplug actions for the Linux Bridge
|
||||
and OpenVSwitch VIF types. Each os-vif plugin will
|
||||
have its own group in nova.conf for configuration
|
||||
parameters it needs. These plugins will be installed
|
||||
by default as part of the os-vif module installation
|
||||
so no special action is required.
|
||||
upgrade:
|
||||
- With the introduction of os-vif, some networking related
|
||||
configuration options have moved, and users will need to update
|
||||
their ``nova.conf``.
|
||||
|
||||
For OpenVSwitch users the following options have moved from
|
||||
``[DEFAULT]`` to ``[vif_plug_ovs]``
|
||||
|
||||
- network_device_mtu
|
||||
- ovs_vsctl_timeout
|
||||
|
||||
For Linux Bridge users the following options have moved from
|
||||
``[DEFAULT]`` to ``[vif_plug_linux_bridge]``
|
||||
|
||||
- use_ipv6
|
||||
- iptables_top_regex
|
||||
- iptables_bottom_regex
|
||||
- iptables_drop_action
|
||||
- forward_bridge_interface
|
||||
- vlan_interface
|
||||
- flat_interface
|
||||
- network_device_mtu
|
||||
|
||||
For backwards compatibility, and ease of upgrade, these options
|
||||
will continue to work from ``[DEFAULT]`` during the Newton
|
||||
release. However they will not in future releases.
|
Loading…
Reference in New Issue
Block a user