Merge "Add support of conntrack-tools in Dom0"

This commit is contained in:
Jenkins 2016-09-08 10:30:23 +00:00 committed by Gerrit Code Review
commit 3057f7fc58
9 changed files with 244 additions and 13 deletions

View File

@ -36,6 +36,7 @@ ${BUILDROOT}/${PLUGIN_NAME}: ${BRANDING} iso
-e s/@PLUGIN_REVISION@/${PLUGIN_REVISION}/g {} \
-e s/@VERSION_HOTFIXES@/${VERSION_HOTFIXES}/g {}
cp suppack/xenapi-plugins-*.iso ${BUILDROOT}/${PLUGIN_NAME}/deployment_scripts/
cp suppack/conntrack-tools.iso ${BUILDROOT}/${PLUGIN_NAME}/deployment_scripts/
${BUILDROOT}/doc/source ${BUILDROOT}/doc/Makefile: ${BRANDING}
mkdir -p ${BUILDROOT}/doc

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
import ConfigParser
from distutils.version import LooseVersion
import logging
import netifaces
import os
@ -16,6 +17,9 @@ LOG_FILE = os.path.join(utils.LOG_ROOT, 'compute_post_deployment.log')
INT_BRIDGE = 'br-int'
XS_PLUGIN_ISO = 'xenapi-plugins-mitaka.iso'
DIST_PACKAGES_DIR = '/usr/lib/python2.7/dist-packages/'
CONNTRACK_ISO = 'conntrack-tools.iso'
CONNTRACK_CONF_SAMPLE =\
'/usr/share/doc/conntrack-tools-1.4.2/doc/stats/conntrackd.conf'
if not os.path.exists(utils.LOG_ROOT):
os.mkdir(utils.LOG_ROOT)
@ -127,12 +131,12 @@ def route_to_compute(endpoints, himn_xs, himn_local, username):
'> /etc/udev/rules.d/90-reroute.rules'))
def install_suppack(himn, username):
def install_suppack(himn, username, package):
"""Install xapi driver supplemental pack. """
tmp = utils.ssh(himn, username, 'mktemp', '-d')
utils.scp(himn, username, tmp, XS_PLUGIN_ISO)
utils.scp(himn, username, tmp, package)
utils.ssh(himn, username, 'xe-install-supplemental-pack',
tmp + '/' + XS_PLUGIN_ISO, prompt='Y\n')
tmp + '/' + package, prompt='Y\n')
utils.ssh(himn, username, 'rm', tmp, '-rf')
@ -306,9 +310,13 @@ def patch_compute_xenapi():
def patch_neutron_ovs_agent():
# MO8's patch is not needed, keep the func here to add
# conntrack patch later
pass
"""Apply neutron patch
Add conntrack-tools patch to support conntrack in Dom0
"""
patchset_dir = sys.path[0]
patch_file = '%s/patchset/fix-xenapi-returncode.patch' % patchset_dir
utils.execute('patch', '-d', '/usr/bin', '-p2', '-i', patch_file)
def reconfig_multipath():
@ -346,6 +354,34 @@ def check_and_setup_ceilometer(himn, username, password):
restart_services('ceilometer-polling')
def enable_conntrack_service(himn, username):
xcp_ver = utils.ssh(himn, username,
('xe host-param-get uuid=$(xe host-list --minimal) '
'param-name=software-version '
'param-key=platform_version'))
if LooseVersion(xcp_ver) < LooseVersion('2.1.0'):
# Only support conntrack-tools since XS7.0(XCP2.1.0) and above
logging.info('No need to enable conntrack-tools with XCP %s' % xcp_ver)
return
conn_installed = utils.ssh(himn, username,
'find', '/usr/sbin', '-name', 'conntrackd')
if not conn_installed:
install_suppack(himn, username, CONNTRACK_ISO)
# use conntrack statistic mode, so change conntrackd.conf
utils.ssh(himn, username,
'mv',
'/etc/conntrackd/conntrackd.conf',
'/etc/conntrackd/conntrackd.conf.back')
utils.ssh(himn, username,
'cp',
CONNTRACK_CONF_SAMPLE,
'/etc/conntrackd/conntrackd.conf')
# Restart conntrackd service
utils.ssh(himn, username, 'service', 'conntrackd', 'restart')
if __name__ == '__main__':
install_xenapi_sdk()
astute = utils.get_astute()
@ -363,7 +399,7 @@ if __name__ == '__main__':
if username and password and endpoints and himn_local:
route_to_compute(endpoints, HIMN_IP, himn_local, username)
if install_xapi:
install_suppack(HIMN_IP, username)
install_suppack(HIMN_IP, username, XS_PLUGIN_ISO)
enable_linux_bridge(HIMN_IP, username)
forward_from_himn(himn_eth)
@ -377,6 +413,9 @@ if __name__ == '__main__':
install_logrotate_script(HIMN_IP, username)
# enable conntrackd service in Dom0
enable_conntrack_service(HIMN_IP, username)
# neutron-l2-agent in compute node
modify_neutron_rootwrap_conf(HIMN_IP, username, password)
br_mappings = find_bridge_mappings(astute, HIMN_IP, username)

View File

@ -0,0 +1,84 @@
diff --git a/bin/neutron-rootwrap-xen-dom0 b/bin/neutron-rootwrap-xen-dom0
index 829b9c1..9210e85 100755
--- a/bin/neutron-rootwrap-xen-dom0
+++ b/bin/neutron-rootwrap-xen-dom0
@@ -29,7 +29,6 @@ from oslo_serialization import jsonutils as json
import os
import select
import sys
-import traceback
import XenAPI
@@ -45,7 +44,7 @@ def parse_args():
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.stderr.write("%s: No command specified" % exec_name)
sys.exit(RC_NOCOMMAND)
config_file = sys.argv.pop(0)
@@ -59,7 +58,7 @@ def _xenapi_section_name(config):
if len(sections) == 1:
return sections[0]
- print("Multiple [xenapi] sections or no [xenapi] section found!")
+ sys.stderr.write("Multiple [xenapi] sections or no [xenapi] section found!")
sys.exit(RC_BADCONFIG)
@@ -74,13 +73,14 @@ def load_configuration(exec_name, config_file):
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.stderr.write("%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.stderr.write(msg)
sys.exit(RC_BADCONFIG)
return dict(
filters_path=filters_path,
@@ -105,7 +105,7 @@ def filter_command(exec_name, filters_path, user_args, exec_dirs):
filter_match = wrapper.match_filter(
filters, user_args, exec_dirs=exec_dirs)
if not filter_match:
- print("Unauthorized command: %s" % ' '.join(user_args))
+ sys.stderr.write("Unauthorized command: %s" % ' '.join(user_args))
sys.exit(RC_UNAUTHORIZED)
@@ -118,11 +118,17 @@ def run_command(url, username, password, user_args, cmd_input):
result = session.xenapi.host.call_plugin(
host, 'netwrap', 'run_command',
{'cmd': json.dumps(user_args), 'cmd_input': json.dumps(cmd_input)})
- return json.loads(result)
+ _out = json.loads(result)
+ returncode = _out.get('returncode')
+ _stdout = _out.get('out')
+ _stderr = _out.get('err')
+ sys.stdout.write(_stdout)
+ sys.stderr.write(_stderr)
+ sys.exit(returncode)
finally:
session.xenapi.session.logout()
except Exception as e:
- traceback.print_exc()
+ sys.stderr.write("Failed to execute command in Dom0, %s" % e)
sys.exit(RC_XENAPI_ERROR)
@@ -142,4 +148,4 @@ def main():
if __name__ == '__main__':
- print(main())
+ main()

View File

@ -0,0 +1,87 @@
#!/usr/bin/env python
# Copyright 2012 OpenStack Foundation
# 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('neutron', unicode=1)
try:
import json
except ImportError:
import simplejson as json
import subprocess
import XenAPIPlugin
ALLOWED_CMDS = [
'ip',
'ipset',
'iptables-save',
'iptables-restore',
'ip6tables-save',
'ip6tables-restore',
'sysctl',
# NOTE(yamamoto): of_interface=native doesn't use ovs-ofctl
'ovs-ofctl',
'ovs-vsctl',
'ovsdb-client',
'conntrack',
]
class PluginError(Exception):
"""Base Exception class for all plugin errors."""
def __init__(self, *args):
Exception.__init__(self, *args)
def _run_command(cmd, cmd_input):
"""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)
(out, err) = proc.communicate(cmd_input)
return proc.returncode, out, err
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)
returncode, out, err = _run_command(
cmd, json.loads(args.get('cmd_input', 'null')))
if not err:
err = ""
if not out:
out = ""
# This runs in Dom0, will return to neutron-ovs-agent in compute node
result = {'returncode': returncode,
'out': out,
'err': err}
return json.dumps(result)
if __name__ == "__main__":
XenAPIPlugin.dispatch({"run_command": run_command})

View File

@ -108,6 +108,7 @@ rm -rf neutron
git clone "$NEUTRON_GITREPO" neutron
pushd neutron
git checkout -b mos_neutron "$GITBRANCH"
cp $FUELPLUG_UTILS_ROOT/../plugin_source/deployment_scripts/patchset/netwrap neutron/plugins/ml2/drivers/openvswitch/agent/xenapi/etc/xapi.d/plugins/
popd
cp -r xenserver-nova-suppack-builder/neutron/* \
@ -118,6 +119,14 @@ popd
NEUTRON_RPMFILE=$(find $FUELPLUG_UTILS_ROOT -name "openstack-neutron-xen-plugins-*.noarch.rpm" -print)
# =============================================
# Find conntrack-tools related RPMs
EXTRA_RPMS=""
EXTRA_RPMS="$EXTRA_RPMS $(find $FUELPLUG_UTILS_ROOT -name "conntrack-tools-*.rpm" -print)"
EXTRA_RPMS="$EXTRA_RPMS $(find $FUELPLUG_UTILS_ROOT -name "libnetfilter_cthelper-*.rpm" -print)"
EXTRA_RPMS="$EXTRA_RPMS $(find $FUELPLUG_UTILS_ROOT -name "libnetfilter_cttimeout-*.rpm" -print)"
EXTRA_RPMS="$EXTRA_RPMS $(find $FUELPLUG_UTILS_ROOT -name "libnetfilter_queue-*.rpm" -print)"
# =============================================
# Create Supplemental pack
@ -133,24 +142,35 @@ from optparse import OptionParser
parser = OptionParser()
parser.add_option('--pdn', dest="product_name")
parser.add_option('--pdv', dest="product_version")
parser.add_option('--desc', dest="description")
parser.add_option('--bld', dest="build")
parser.add_option('--out', dest="outdir")
(options, args) = parser.parse_args()
xcp = Requires(originator='xcp', name='main', test='ge',
product='XenServer', version='$PLATFORM_VERSION',
build='$XS_BUILD')
product='XenServer', version=options.product_version,
build=options.build)
setup(originator='xcp', name='xenapi-plugins-$OS_RELEASE', product='XenServer',
setup(originator='xcp', name=options.product_name, product='XenServer',
version=options.product_version, build=options.build, vendor='Citrix Systems, Inc.',
description="OpenStack XenServer Plugins", packages=args, requires=[xcp],
description=options.description, packages=args, requires=[xcp],
outdir=options.outdir, output=['iso'])
EOF
python buildscript.py \
--pdn=xenserverplugins \
--pdv=$OS_RELEASE \
--pdn=xenapi-plugins-$OS_RELEASE \
--pdv=$PLATFORM_VERSION \
--desc="OpenStack XenServer Plugins" \
--bld=0 \
--out=$FUELPLUG_UTILS_ROOT \
$RPMFILE \
$NEUTRON_RPMFILE
python buildscript.py \
--pdn=conntrack-tools \
--pdv=$PLATFORM_VERSION \
--desc="XenServer Dom0 conntrack-tools" \
--bld=0 \
--out=$FUELPLUG_UTILS_ROOT \
$EXTRA_RPMS