Merge "Add support for OVS l2 agent in XS/XCP domU."
This commit is contained in:
commit
bf5deb5c65
119
bin/quantum-rootwrap-xen-dom0
Executable file
119
bin/quantum-rootwrap-xen-dom0
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2012 Openstack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Quantum root wrapper for dom0.
|
||||
|
||||
Executes networking commands in dom0. The XenAPI plugin is
|
||||
responsible determining whether a command is safe to execute.
|
||||
|
||||
"""
|
||||
|
||||
import ConfigParser
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import XenAPI
|
||||
|
||||
|
||||
RC_UNAUTHORIZED = 99
|
||||
RC_NOCOMMAND = 98
|
||||
RC_BADCONFIG = 97
|
||||
RC_XENAPI_ERROR = 96
|
||||
|
||||
|
||||
def parse_args():
|
||||
# Split arguments, require at least a command
|
||||
exec_name = sys.argv.pop(0)
|
||||
# argv[0] required; path to conf file
|
||||
if len(sys.argv) < 2:
|
||||
print "%s: No command specified" % exec_name
|
||||
sys.exit(RC_NOCOMMAND)
|
||||
|
||||
config_file = sys.argv.pop(0)
|
||||
user_args = sys.argv[:]
|
||||
|
||||
return exec_name, config_file, user_args
|
||||
|
||||
|
||||
def load_configuration(exec_name, config_file):
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.read(config_file)
|
||||
try:
|
||||
filters_path = config.get("DEFAULT", "filters_path").split(",")
|
||||
section = 'XENAPI'
|
||||
url = config.get(section, "xenapi_connection_url")
|
||||
username = config.get(section, "xenapi_connection_username")
|
||||
password = config.get(section, "xenapi_connection_password")
|
||||
except ConfigParser.Error:
|
||||
print "%s: Incorrect configuration file: %s" % (exec_name, config_file)
|
||||
sys.exit(RC_BADCONFIG)
|
||||
if not url or not password:
|
||||
msg = ("%s: Must specify xenapi_connection_url, "
|
||||
"xenapi_connection_username (optionally), and "
|
||||
"xenapi_connection_password in %s") % (exec_name, config_file)
|
||||
print msg
|
||||
sys.exit(RC_BADCONFIG)
|
||||
return dict(
|
||||
filters_path=filters_path,
|
||||
url=url,
|
||||
username=username,
|
||||
password=password,
|
||||
)
|
||||
|
||||
|
||||
def filter_command(exec_name, filters_path, user_args):
|
||||
# Add ../ to sys.path to allow running from branch
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(exec_name),
|
||||
os.pardir, os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir, "quantum", "__init__.py")):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
from quantum.rootwrap import wrapper
|
||||
|
||||
# Execute command if it matches any of the loaded filters
|
||||
filters = wrapper.load_filters(filters_path)
|
||||
filter_match = wrapper.match_filter(filters, user_args)
|
||||
if not filter_match:
|
||||
print "Unauthorized command: %s" % ' '.join(user_args)
|
||||
sys.exit(RC_UNAUTHORIZED)
|
||||
|
||||
|
||||
def run_command(url, username, password, user_args):
|
||||
try:
|
||||
session = XenAPI.Session(url)
|
||||
session.login_with_password(username, password)
|
||||
host = session.xenapi.session.get_this_host(session.handle)
|
||||
result = session.xenapi.host.call_plugin(
|
||||
host, 'netwrap', 'run_command', {'cmd': json.dumps(user_args)})
|
||||
return json.loads(result)
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
sys.exit(RC_XENAPI_ERROR)
|
||||
|
||||
|
||||
def main():
|
||||
exec_name, config_file, user_args = parse_args()
|
||||
config = load_configuration(exec_name, config_file)
|
||||
filter_command(exec_name, config['filters_path'], user_args)
|
||||
return run_command(config['url'], config['username'], config['password'],
|
||||
user_args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print main()
|
@ -2,3 +2,10 @@
|
||||
# List of directories to load filter definitions from (separated by ',').
|
||||
# These directories MUST all be only writeable by root !
|
||||
filters_path=/etc/quantum/rootwrap.d,/usr/share/quantum/rootwrap
|
||||
|
||||
[XENAPI]
|
||||
# XenAPI configuration is only required by the L2 agent if it is to
|
||||
# target a XenServer/XCP compute host's dom0.
|
||||
xenapi_connection_url=<None>
|
||||
xenapi_connection_username=root
|
||||
xenapi_connection_password=<None>
|
||||
|
@ -15,11 +15,19 @@
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from oslo.config import cfg
|
||||
|
||||
from quantum.agent.linux import utils
|
||||
from quantum.common import exceptions
|
||||
|
||||
|
||||
OPTS = [
|
||||
cfg.BoolOpt('ip_lib_force_root',
|
||||
default=False,
|
||||
help=_('Force ip_lib calls to use the root helper')),
|
||||
]
|
||||
|
||||
|
||||
LOOPBACK_DEVNAME = 'lo'
|
||||
|
||||
|
||||
@ -27,10 +35,20 @@ class SubProcessBase(object):
|
||||
def __init__(self, root_helper=None, namespace=None):
|
||||
self.root_helper = root_helper
|
||||
self.namespace = namespace
|
||||
try:
|
||||
self.force_root = cfg.CONF.ip_lib_force_root
|
||||
except cfg.NoSuchOptError:
|
||||
# Only callers that need to force use of the root helper
|
||||
# need to register the option.
|
||||
self.force_root = False
|
||||
|
||||
def _run(self, options, command, args):
|
||||
if self.namespace:
|
||||
return self._as_root(options, command, args)
|
||||
elif self.force_root:
|
||||
# Force use of the root helper to ensure that commands
|
||||
# will execute in dom0 when running under XenServer/XCP.
|
||||
return self._execute(options, command, args, self.root_helper)
|
||||
else:
|
||||
return self._execute(options, command, args)
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
import re
|
||||
|
||||
from quantum.agent.linux import ip_lib
|
||||
from quantum.agent.linux import utils
|
||||
from quantum.openstack.common import log as logging
|
||||
|
||||
@ -283,6 +284,15 @@ class OVSBridge:
|
||||
for port_name in port_names:
|
||||
self.delete_port(port_name)
|
||||
|
||||
def get_local_port_mac(self):
|
||||
"""Retrieve the mac of the bridge's local port."""
|
||||
address = ip_lib.IPDevice(self.br_name, self.root_helper).link.address
|
||||
if address:
|
||||
return address
|
||||
else:
|
||||
msg = _('Unable to determine mac address for %s') % self.br_name
|
||||
raise Exception(msg)
|
||||
|
||||
|
||||
def get_bridge_for_iface(root_helper, iface):
|
||||
args = ["ovs-vsctl", "--timeout=2", "iface-to-br", iface]
|
||||
|
@ -1,54 +0,0 @@
|
||||
# TODO(bgh): DIST_DIR and target for plugin
|
||||
PHONY: help
|
||||
|
||||
AGENT_DIST_DIR=ovs_quantum_agent
|
||||
AGENT_DIST_TARBALL=ovs_quantum_agent.tgz
|
||||
VERSION=$(shell python -c "import sys ; sys.path.append('../../../quantum/') ; import version ; print version.canonical_version_string()")
|
||||
XAPI_PLUGINS_DIR=$(AGENT_DIST_DIR)/build/ovs-quantum-agent-$(VERSION)/etc/xapi.d/plugins
|
||||
RPM_BUILD_ROOT=$(AGENT_DIST_DIR)/build/rpm
|
||||
|
||||
help:
|
||||
@echo "make agent-dist-xen - to create the ovs-quantum-agent-${VERSION}-1.noarch.rpm"
|
||||
@echo "make agent-dist-xen-python26 - to create ovs-quantum-agent-${VERSION}-1.noarch.rpm and use python2.6"
|
||||
|
||||
agent-dist-xen:QUANTUM_LIBS=$(AGENT_DIST_DIR)/build/ovs-quantum-agent-$(VERSION)/usr/lib/python2.4/site-packages
|
||||
agent-dist-xen-python26:QUANTUM_LIBS=$(AGENT_DIST_DIR)/build/ovs-quantum-agent-$(VERSION)/usr/lib/python2.6/site-packages
|
||||
|
||||
agent-dist-xen agent-dist-xen-python26: distclean
|
||||
yum --enablerepo=base install rpm-build
|
||||
mkdir -p $(XAPI_PLUGINS_DIR)
|
||||
mkdir -p $(QUANTUM_LIBS)/{quantum/plugins/openvswitch/common,quantum/openstack/common}
|
||||
mkdir -p $(QUANTUM_LIBS)/quantum/agent/linux
|
||||
mkdir -p $(RPM_BUILD_ROOT)/BUILD $(RPM_BUILD_ROOT)/SOURCES
|
||||
mkdir -p $(RPM_BUILD_ROOT)/SRPMS $(RPM_BUILD_ROOT)/RPMS $(RPM_BUILD_ROOT)/SPECS
|
||||
cp agent/*.py $(XAPI_PLUGINS_DIR)
|
||||
cp agent/*.sh $(AGENT_DIST_DIR)
|
||||
cp agent/ovs-quantum-agent-xs_xcp.spec $(AGENT_DIST_DIR)
|
||||
sed -i "s/VERSION/$(VERSION)/" $(AGENT_DIST_DIR)/ovs-quantum-agent-xs_xcp.spec
|
||||
cp README $(AGENT_DIST_DIR)
|
||||
cp ../../../etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini $(XAPI_PLUGINS_DIR)
|
||||
cp ../../agent/linux/{ovs_lib.py,utils.py,__init__.py} $(QUANTUM_LIBS)/quantum/agent/linux
|
||||
test -d $(AGENT_DIST_DIR)/build/ovs-quantum-agent-$(VERSION)/usr/lib/python2.6/site-packages && \
|
||||
sed -i 's/Requires:.*/Requires: python26 python26-sqlalchemy python26-mysqldb/' \
|
||||
$(AGENT_DIST_DIR)/ovs-quantum-agent-xs_xcp.spec || true
|
||||
test -d $(AGENT_DIST_DIR)/build/ovs-quantum-agent-$(VERSION)/usr/lib/python2.6/site-packages && \
|
||||
sed -i 's/env python/env python2.6/' $(XAPI_PLUGINS_DIR)/ovs_quantum_agent.py || true
|
||||
cp ../../__init__.py $(QUANTUM_LIBS)/quantum/
|
||||
cp ../../agent/__init__.py $(QUANTUM_LIBS)/quantum/agent/
|
||||
cp ../__init__.py $(QUANTUM_LIBS)/quantum/plugins/
|
||||
cp __init__.py $(QUANTUM_LIBS)/quantum/plugins/openvswitch/
|
||||
cp common/{config.py,__init__.py} $(QUANTUM_LIBS)/quantum/plugins/openvswitch/common/
|
||||
cp ../../openstack/__init__.py $(QUANTUM_LIBS)/quantum/openstack/
|
||||
tar -czvpf ${RPM_BUILD_ROOT}/SOURCES/ovs-quantum-agent-${VERSION}.tgz -C $(AGENT_DIST_DIR)/build ovs-quantum-agent-${VERSION}
|
||||
rpmbuild -ba --define "_topdir $(shell pwd)/$(RPM_BUILD_ROOT)" --clean $(AGENT_DIST_DIR)/ovs-quantum-agent-xs_xcp.spec
|
||||
@echo "Agent package created: ovs_quantum_agent/build/rpm/RPMS/noarch/ovs-quantum-agent-${VERSION}-1.noarch.rpm"
|
||||
@echo "See README for installation details"
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
$(find . -name *.pyc | xargs rm)
|
||||
|
||||
distclean:
|
||||
-rm -rf $(AGENT_DIST_DIR)
|
||||
-rm -f $(AGENT_DIST_TARBALL)
|
@ -1,33 +0,0 @@
|
||||
Name: ovs-quantum-agent
|
||||
Version: VERSION
|
||||
Release: 1
|
||||
License: Apache2
|
||||
Group: System Environment/Base
|
||||
Summary: Ovs Quantum Agent
|
||||
Source: %{name}-%{version}.tgz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
BuildArch: noarch
|
||||
Requires: python python-sqlalchemy
|
||||
|
||||
%description
|
||||
OVS Quantum Agent
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%install
|
||||
rm -rf --preserve-root %{buildroot}
|
||||
install -d -m 755 %{buildroot}
|
||||
cp -af * %{buildroot}
|
||||
pushd %{buildroot}
|
||||
find ./usr ./etc -type f -o -type l | sed "s/\.//" > %{_builddir}/%{name}-%{version}/%{name}-%{version}-%{release}-filelist
|
||||
popd
|
||||
|
||||
%clean
|
||||
[ %{buildroot} != / ] && rm -rf %{buildroot}
|
||||
|
||||
%files -f %{_builddir}/%{name}-%{version}/%{name}-%{version}-%{release}-filelist
|
||||
|
||||
%changelog
|
||||
* Thu Jun 14 2012 Juliano Martinez <juliano.martinez@locaweb.com.br> - VERSION
|
||||
- Creating quantum ovs agent package
|
@ -28,7 +28,6 @@ from oslo.config import cfg
|
||||
|
||||
from quantum.agent.linux import ip_lib
|
||||
from quantum.agent.linux import ovs_lib
|
||||
from quantum.agent.linux import utils
|
||||
from quantum.agent import rpc as agent_rpc
|
||||
from quantum.agent import securitygroups_rpc as sg_rpc
|
||||
from quantum.common import config as logging_config
|
||||
@ -179,7 +178,7 @@ class OVSQuantumAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
||||
'configurations': bridge_mappings,
|
||||
'agent_type': q_const.AGENT_TYPE_OVS,
|
||||
'start_flag': True}
|
||||
self.setup_rpc(integ_br)
|
||||
self.setup_rpc()
|
||||
|
||||
# Security group agent supprot
|
||||
self.sg_agent = OVSSecurityGroupAgent(self.context,
|
||||
@ -198,8 +197,8 @@ class OVSQuantumAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
||||
except Exception:
|
||||
LOG.exception(_("Failed reporting state!"))
|
||||
|
||||
def setup_rpc(self, integ_br):
|
||||
mac = utils.get_interface_mac(integ_br)
|
||||
def setup_rpc(self):
|
||||
mac = self.int_br.get_local_port_mac()
|
||||
self.agent_id = '%s%s' % ('ovs', (mac.replace(":", "")))
|
||||
self.topic = topics.AGENT
|
||||
self.plugin_rpc = OVSPluginApi(topics.PLUGIN)
|
||||
@ -760,6 +759,7 @@ def create_agent_config_map(config):
|
||||
def main():
|
||||
eventlet.monkey_patch()
|
||||
cfg.CONF(project='quantum')
|
||||
cfg.CONF.register_opts(ip_lib.OPTS)
|
||||
logging_config.setup_logging(cfg.CONF)
|
||||
|
||||
try:
|
||||
@ -768,6 +768,12 @@ def main():
|
||||
LOG.error(_('%s Agent terminated!'), e)
|
||||
sys.exit(1)
|
||||
|
||||
is_xen_compute_host = 'rootwrap-xen-dom0' in agent_config['root_helper']
|
||||
if is_xen_compute_host:
|
||||
# Force ip_lib to always use the root helper to ensure that ip
|
||||
# commands target xen dom0 rather than domU.
|
||||
cfg.CONF.set_default('ip_lib_force_root', True)
|
||||
|
||||
plugin = OVSQuantumAgent(**agent_config)
|
||||
|
||||
# Start everything.
|
||||
|
16
quantum/plugins/openvswitch/agent/xenapi/README
Normal file
16
quantum/plugins/openvswitch/agent/xenapi/README
Normal file
@ -0,0 +1,16 @@
|
||||
This directory contains files that are required for the XenAPI support.
|
||||
They should be installed in the XenServer / Xen Cloud Platform dom0.
|
||||
|
||||
If you install them manually, you will need to ensure that the newly
|
||||
added files are executable. You can do this by running the following
|
||||
command (from dom0):
|
||||
|
||||
chmod a+x /etc/xapi.d/plugins/*
|
||||
|
||||
Otherwise, you can build an rpm by running the following command:
|
||||
|
||||
./contrib/build-rpm.sh
|
||||
|
||||
and install the rpm by running the following command (from dom0):
|
||||
|
||||
rpm -i openstack-quantum-xen-plugins.rpm
|
34
quantum/plugins/openvswitch/agent/xenapi/contrib/build-rpm.sh
Executable file
34
quantum/plugins/openvswitch/agent/xenapi/contrib/build-rpm.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eux
|
||||
|
||||
thisdir=$(dirname $(readlink -f "$0"))
|
||||
export QUANTUM_ROOT="$thisdir/../../../../../../"
|
||||
export PYTHONPATH=$QUANTUM_ROOT
|
||||
|
||||
cd $QUANTUM_ROOT
|
||||
VERSION=$(sh -c "(cat $QUANTUM_ROOT/quantum/version.py; \
|
||||
echo 'print common_version.VersionInfo(\"quantum\").release_string()') | \
|
||||
python")
|
||||
cd -
|
||||
|
||||
PACKAGE=openstack-quantum-xen-plugins
|
||||
RPMBUILD_DIR=$PWD/rpmbuild
|
||||
if [ ! -d $RPMBUILD_DIR ]; then
|
||||
echo $RPMBUILD_DIR is missing
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for dir in BUILD BUILDROOT SRPMS RPMS SOURCES; do
|
||||
rm -rf $RPMBUILD_DIR/$dir
|
||||
mkdir -p $RPMBUILD_DIR/$dir
|
||||
done
|
||||
|
||||
rm -rf /tmp/$PACKAGE
|
||||
mkdir /tmp/$PACKAGE
|
||||
cp -r ../etc/xapi.d /tmp/$PACKAGE
|
||||
tar czf $RPMBUILD_DIR/SOURCES/$PACKAGE.tar.gz -C /tmp $PACKAGE
|
||||
|
||||
rpmbuild -ba --nodeps --define "_topdir $RPMBUILD_DIR" \
|
||||
--define "version $VERSION" \
|
||||
$RPMBUILD_DIR/SPECS/$PACKAGE.spec
|
@ -0,0 +1,30 @@
|
||||
Name: openstack-quantum-xen-plugins
|
||||
Version: %{version}
|
||||
Release: 1
|
||||
Summary: Files for XenAPI support.
|
||||
License: ASL 2.0
|
||||
Group: Applications/Utilities
|
||||
Source0: openstack-quantum-xen-plugins.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
%define debug_package %{nil}
|
||||
|
||||
%description
|
||||
This package contains files that are required for XenAPI support for Quantum.
|
||||
|
||||
%prep
|
||||
%setup -q -n openstack-quantum-xen-plugins
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir -p $RPM_BUILD_ROOT/etc
|
||||
cp -r xapi.d $RPM_BUILD_ROOT/etc
|
||||
chmod a+x $RPM_BUILD_ROOT/etc/xapi.d/plugins/*
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
/etc/xapi.d/plugins/*
|
@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2012 OpenStack LLC.
|
||||
# Copyright 2012 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
#
|
||||
# XenAPI plugin for executing network commands (ovs, iptables, etc) on dom0
|
||||
#
|
||||
|
||||
import gettext
|
||||
gettext.install('quantum', unicode=1)
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
import subprocess
|
||||
|
||||
import XenAPIPlugin
|
||||
|
||||
|
||||
ALLOWED_CMDS = [
|
||||
'ip',
|
||||
'ovs-ofctl',
|
||||
'ovs-vsctl',
|
||||
]
|
||||
|
||||
|
||||
class PluginError(Exception):
|
||||
"""Base Exception class for all plugin errors."""
|
||||
def __init__(self, *args):
|
||||
Exception.__init__(self, *args)
|
||||
|
||||
|
||||
def _run_command(cmd):
|
||||
"""Abstracts out the basics of issuing system commands. If the command
|
||||
returns anything in stderr, a PluginError is raised with that information.
|
||||
Otherwise, the output from stdout is returned.
|
||||
"""
|
||||
pipe = subprocess.PIPE
|
||||
proc = subprocess.Popen(cmd, shell=False, stdin=pipe, stdout=pipe,
|
||||
stderr=pipe, close_fds=True)
|
||||
proc.wait()
|
||||
err = proc.stderr.read()
|
||||
if err:
|
||||
raise PluginError(err)
|
||||
return proc.stdout.read()
|
||||
|
||||
|
||||
def run_command(session, args):
|
||||
cmd = json.loads(args.get('cmd'))
|
||||
if cmd and cmd[0] not in ALLOWED_CMDS:
|
||||
msg = _("Dom0 execution of '%s' is not permitted") % cmd[0]
|
||||
raise PluginError(msg)
|
||||
result = _run_command(cmd)
|
||||
return json.dumps(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
XenAPIPlugin.dispatch({"run_command": run_command})
|
@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CONF_FILE=/etc/xapi.d/plugins/ovs_quantum_plugin.ini
|
||||
VERSION=$(python -c "import sys ; sys.path.append('../../../../quantum/') ; import version ; print version.canonical_version_string()")
|
||||
|
||||
if [ ! -d /etc/xapi.d/plugins ]; then
|
||||
echo "Am I on a xenserver? I can't find the plugins directory!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm
|
||||
|
||||
if [ "$1" == "with_python_2.6" ] ; then
|
||||
yum --enablerepo=base -y install mx
|
||||
yum --enablerepo=epel -y install python26 python26-sqlalchemy python26-mysqldb
|
||||
else
|
||||
yum --enablerepo=epel -y install python-sqlalchemy
|
||||
yum --enablerepo=base -y install MySQL-python
|
||||
fi
|
||||
|
||||
sed -i 's/enabled=1/enabled=0/' /etc/yum.repos.d/epel.repo
|
||||
|
||||
rpm -Uvh $PWD/build/rpm/RPMS/noarch/ovs-quantum-agent-$VERSION-1.noarch.rpm
|
||||
|
||||
xe network-list name-label="integration-bridge" | grep xapi >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "No integration bridge found. Creating."
|
||||
xe network-create name-label="integration-bridge"
|
||||
fi
|
||||
|
||||
BR=$(xe network-list name-label="integration-bridge" | grep "bridge.*:" | awk '{print $4}')
|
||||
CONF_BR=$(grep integration-bridge ${CONF_FILE} | cut -d= -f2)
|
||||
if [ "X$BR" != "X$CONF_BR" ]; then
|
||||
echo "Integration bridge doesn't match configuration file; fixing."
|
||||
sed -i -e "s/^integration-bridge =.*$/integration-bridge = ${BR}/g" $CONF_FILE
|
||||
fi
|
||||
|
||||
echo "Using integration bridge: $BR (make sure this is set in the nova configuration)"
|
||||
|
||||
echo "Make sure to edit: $CONF_FILE"
|
@ -15,7 +15,9 @@
|
||||
# under the License.
|
||||
# @author: Dan Wendlandt, Nicira, Inc.
|
||||
|
||||
import mock
|
||||
import mox
|
||||
import testtools
|
||||
|
||||
from quantum.agent.linux import ovs_lib, utils
|
||||
from quantum.openstack.common import uuidutils
|
||||
@ -344,3 +346,14 @@ class OVS_Lib_Test(base.BaseTestCase):
|
||||
self.mox.ReplayAll()
|
||||
self.assertEqual(ovs_lib.get_bridges(root_helper), bridges)
|
||||
self.mox.VerifyAll()
|
||||
|
||||
def test_get_local_port_mac_succeeds(self):
|
||||
with mock.patch('quantum.agent.linux.ip_lib.IpLinkCommand',
|
||||
return_value=mock.Mock(address='foo')):
|
||||
self.assertEqual('foo', self.br.get_local_port_mac())
|
||||
|
||||
def test_get_local_port_mac_raises_exception_for_missing_mac(self):
|
||||
with mock.patch('quantum.agent.linux.ip_lib.IpLinkCommand',
|
||||
return_value=mock.Mock(address=None)):
|
||||
with testtools.ExpectedException(Exception):
|
||||
self.br.get_local_port_mac()
|
||||
|
@ -21,7 +21,6 @@ from oslo.config import cfg
|
||||
|
||||
from quantum.agent.linux import ip_lib
|
||||
from quantum.agent.linux import ovs_lib
|
||||
from quantum.agent.linux import utils
|
||||
from quantum.openstack.common import log
|
||||
from quantum.plugins.openvswitch.agent import ovs_quantum_agent
|
||||
from quantum.plugins.openvswitch.common import constants
|
||||
@ -123,9 +122,7 @@ class TunnelTest(base.BaseTestCase):
|
||||
'int-tunnel_bridge_mapping',
|
||||
'phy-tunnel_bridge_mapping').AndReturn([self.inta, self.intb])
|
||||
|
||||
self.mox.StubOutWithMock(utils, 'get_interface_mac')
|
||||
utils.get_interface_mac(self.INT_BRIDGE).AndReturn(
|
||||
'00:00:00:00:00:01')
|
||||
self.mock_int_bridge.get_local_port_mac().AndReturn('000000000001')
|
||||
|
||||
def testConstruct(self):
|
||||
self.mox.ReplayAll()
|
||||
|
Loading…
Reference in New Issue
Block a user