Move libvirt VIF XML config into designer.py

There are a fixed set of sensible XML configurations for
network VIFs. Create some helper methods for configuring
these configurations. Then update the VIF drivers to call
these APIs. The 'designer.py' file will serve as a place
for any policy based XML configuration helpers, as distinct
from config.py which is purely dealing with XML parsing
and formatting

Blueprint: libvirt-vif-driver
Change-Id: I857607c15ed576c65f898df4eb7533505742324b
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2013-01-03 16:51:23 +00:00
parent 567bbd1861
commit bcb99833e7
3 changed files with 138 additions and 36 deletions

View File

@ -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

View File

@ -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)

View File

@ -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'])
designer.set_vif_host_backend_bridge_config(
conf, network['bridge'], None)
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']:
conf.add_filter_param("DHCPSERVER", mapping['dhcp_server'])
dhcp_server = mapping['dhcp_server']
if CONF.use_ipv6:
conf.add_filter_param("RASERVER",
mapping.get('gateway_v6') + "/128")
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