diff options
-rw-r--r-- | nova/virt/libvirt/config.py | 8 | ||||
-rw-r--r-- | nova/virt/libvirt/designer.py | 101 | ||||
-rw-r--r-- | nova/virt/libvirt/vif.py | 65 |
3 files changed, 138 insertions, 36 deletions
diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index 222e6d52d..6785c8823 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -1,6 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2012 Red Hat, Inc. +# Copyright (C) 2012-2013 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 @@ -18,7 +18,11 @@ Configuration for libvirt objects. Classes to represent the configuration of various libvirt objects -and support conversion to/from XML +and support conversion to/from XML. These classes are solely concerned +by providing direct Object <-> XML document conversions. No policy or +operational decisions should be made by code in these classes. Such +policy belongs in the 'designer.py' module which provides simplified +helpers for populating up config object instances. """ from nova import exception diff --git a/nova/virt/libvirt/designer.py b/nova/virt/libvirt/designer.py new file mode 100644 index 000000000..b832db4fa --- /dev/null +++ b/nova/virt/libvirt/designer.py @@ -0,0 +1,101 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (C) 2013 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 +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Policy based configuration of libvirt objects + +This module provides helper APIs for populating the config.py +classes based on common operational needs / policies +""" + +from nova.virt import netutils + + +def set_vif_guest_frontend_config(conf, mac, model, driver): + """Populate a LibvirtConfigGuestInterface instance + with guest frontend details""" + conf.mac_addr = mac + if model is not None: + conf.model = model + if driver is not None: + conf.driver_name = driver + + +def set_vif_host_backend_bridge_config(conf, brname, tapname=None): + """Populate a LibvirtConfigGuestInterface instance + with host backend details for a software bridge""" + conf.net_type = "bridge" + conf.source_dev = brname + if tapname: + conf.target_dev = tapname + conf.script = "" + + +def set_vif_host_backend_ethernet_config(conf, tapname): + """Populate a LibvirtConfigGuestInterface instance + with host backend details for an externally configured + host device. + + NB use of this configuration is discouraged by + libvirt project and will mark domains as 'tainted'""" + + conf.net_type = "ethernet" + conf.target_dev = 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 + conf.script = "" + + +def set_vif_host_backend_filter_config(conf, name, + primary_addr, + dhcp_server=None, + ra_server=None, + allow_same_net=False, + ipv4_cidr=None, + ipv6_cidr=None): + """Populate a LibvirtConfigGuestInterface instance + with host backend details for traffic filtering""" + + conf.filtername = name + conf.add_filter_param("IP", primary_addr) + + if dhcp_server: + conf.add_filter_param("DHCPSERVER", dhcp_server) + + if ra_server: + conf.add_filter_param("RASERVER", ra_server) + + if allow_same_net: + if ipv4_cidr: + net, mask = netutils.get_net_and_mask(ipv4_cidr) + conf.add_filter_param("PROJNET", net) + conf.add_filter_param("PROJMASK", mask) + + if ipv6_cidr: + net, prefix = netutils.get_net_and_prefixlen(ipv6_cidr) + conf.add_filter_param("PROJNET6", net) + conf.add_filter_param("PROJMASK6", prefix) diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 1dc30f73e..0cf1b1658 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -24,10 +24,10 @@ from nova.network import linux_net from nova.openstack.common import cfg from nova.openstack.common import log as logging from nova import utils -from nova.virt import netutils from nova.virt.libvirt import config as vconfig - +from nova.virt.libvirt import designer +from nova.virt import netutils LOG = logging.getLogger(__name__) libvirt_vif_opts = [ @@ -51,14 +51,18 @@ class LibvirtBaseVIFDriver(object): def get_config(self, instance, network, mapping): conf = vconfig.LibvirtConfigGuestInterface() - conf.mac_addr = mapping['mac'] - if CONF.libvirt_type in ('kvm', 'qemu') and \ - CONF.libvirt_use_virtio_for_bridges: - conf.model = "virtio" + model = None + driver = None + if (CONF.libvirt_type in ('kvm', 'qemu') and + CONF.libvirt_use_virtio_for_bridges): + model = "virtio" # Workaround libvirt bug, where it mistakenly # enables vhost mode, even for non-KVM guests if CONF.libvirt_type == "qemu": - conf.driver_name = "qemu" + driver = "qemu" + + designer.set_vif_guest_frontend_config( + conf, mapping['mac'], model, driver) return conf @@ -75,28 +79,26 @@ class LibvirtBridgeDriver(LibvirtBaseVIFDriver): self).get_config(instance, network, mapping) - conf.net_type = "bridge" - conf.source_dev = network['bridge'] - conf.script = "" - conf.filtername = "nova-instance-" + instance['name'] + "-" + mac_id - conf.add_filter_param("IP", mapping['ips'][0]['ip']) - if mapping['dhcp_server']: - conf.add_filter_param("DHCPSERVER", mapping['dhcp_server']) + designer.set_vif_host_backend_bridge_config( + conf, network['bridge'], None) - if CONF.use_ipv6: - conf.add_filter_param("RASERVER", - mapping.get('gateway_v6') + "/128") + name = "nova-instance-" + instance['name'] + "-" + mac_id + primary_addr = mapping['ips'][0]['ip'] + dhcp_server = ra_server = ipv4_cidr = ipv6_cidr = None + if mapping['dhcp_server']: + dhcp_server = mapping['dhcp_server'] + if CONF.use_ipv6: + ra_server = mapping.get('gateway_v6') + "/128" if CONF.allow_same_net_traffic: - net, mask = netutils.get_net_and_mask(network['cidr']) - conf.add_filter_param("PROJNET", net) - conf.add_filter_param("PROJMASK", mask) + ipv4_cidr = network['cidr'] if CONF.use_ipv6: - net_v6, prefixlen_v6 = netutils.get_net_and_prefixlen( - network['cidr_v6']) - conf.add_filter_param("PROJNET6", net_v6) - conf.add_filter_param("PROJMASK6", prefixlen_v6) + ipv6_cidr = network['cidr_v6'] + + designer.set_vif_host_backend_filter_config( + conf, name, primary_addr, dhcp_server, + ra_server, ipv4_cidr, ipv6_cidr) return conf @@ -146,9 +148,7 @@ class LibvirtOpenVswitchDriver(LibvirtBaseVIFDriver): network, mapping) - conf.net_type = "ethernet" - conf.target_dev = dev - conf.script = "" + designer.set_vif_host_backend_ethernet_config(conf, dev) return conf @@ -279,10 +279,8 @@ class LibvirtOpenVswitchVirtualPortDriver(LibvirtBaseVIFDriver): network, mapping) - conf.net_type = "bridge" - conf.source_dev = CONF.libvirt_ovs_bridge - conf.vporttype = "openvswitch" - conf.add_vport_param("interfaceid", mapping['vif_uuid']) + designer.set_vif_host_backend_ovs_config( + conf, CONF.libvirt_ovs_bridge, mapping['vif_uuid']) return conf @@ -316,9 +314,8 @@ class QuantumLinuxBridgeVIFDriver(LibvirtBaseVIFDriver): network, mapping) - conf.target_dev = dev - conf.net_type = "bridge" - conf.source_dev = bridge + designer.set_vif_host_backend_bridge_config( + conf, bridge, dev) return conf |