Add configuration file to dragonflow local controller

This patch introduce configuration file to dragonflow parameters in
the plugin and in the local controller.
One of the parameters is the pluggable DB layer which can be
changed in the configuration.

Change-Id: Ida2ee8ecbf794274f682fb1e75df830f2aed14e6
This commit is contained in:
Gal Sagie 2015-08-18 11:47:34 +03:00
parent 312b6bbdab
commit e1d7b5afb4
7 changed files with 89 additions and 37 deletions

View File

@ -7,9 +7,14 @@ OVN_REPO_NAME=$(basename ${OVN_REPO} | cut -f1 -d'.')
# The branch to use from $OVN_REPO
OVN_BRANCH=${OVN_BRANCH:-origin/master}
DEFAULT_NB_DRIVER_CLASS="dragonflow.db.drivers.etcd_nb_impl.EtcdNbApi"
DEFAULT_TUNNEL_TYPE="geneve"
# How to connect to ovsdb-server hosting the OVN databases.
REMOTE_DB_IP=${REMOTE_DB_IP:-$HOST_IP}
REMOTE_DB_PORT=${REMOTE_DB_PORT:-4001}
NB_DRIVER_CLASS=${NB_DRIVER_CLASS:-$DEFAULT_NB_DRIVER_CLASS}
TUNNEL_TYPE=${TUNNEL_TYPE:-$DEFAULT_TUNNEL_TYPE}
# Entry Points
# ------------
@ -23,9 +28,24 @@ function configure_df_plugin {
NEUTRON_CONF=/etc/neutron/neutron.conf
iniset $NEUTRON_CONF df remote_db_ip "$REMOTE_DB_IP"
iniset $NEUTRON_CONF df remote_db_port $REMOTE_DB_PORT
iniset $NEUTRON_CONF df nb_db_class "$NB_DRIVER_CLASS"
iniset $NEUTRON_CONF df local_ip "$HOST_IP"
iniset $NEUTRON_CONF df tunnel_type "$TUNNEL_TYPE"
iniset $NEUTRON_CONF DEFAULT core_plugin "$Q_PLUGIN_CLASS"
iniset $NEUTRON_CONF DEFAULT service_plugins ""
fi
if ! is_service_enabled q-svc; then
_create_neutron_conf_dir
NEUTRON_CONF=/etc/neutron/neutron.conf
cp $NEUTRON_DIR/etc/neutron.conf $NEUTRON_CONF
iniset $NEUTRON_CONF df remote_db_ip "$REMOTE_DB_IP"
iniset $NEUTRON_CONF df remote_db_port $REMOTE_DB_PORT
iniset $NEUTRON_CONF df nb_db_class "$NB_DRIVER_CLASS"
iniset $NEUTRON_CONF df local_ip "$HOST_IP"
iniset $NEUTRON_CONF df tunnel_type "$TUNNEL_TYPE"
fi
}
# init_ovn() - Initialize databases, etc.
@ -55,7 +75,7 @@ function init_ovn {
function install_df {
echo_summary "Installing etcd"
if is_service_enabled df-etcd ; then
rm -rf default.etcd
rm -rf $DEST/data/ovs/default.etcd
if [ ! -f "/opt/stack/etcd/etcd-v2.1.1-linux-amd64/etcd" ]; then
echo "Installing etcd server"
mkdir /opt/stack/etcd
@ -179,7 +199,7 @@ function start_df {
if is_service_enabled df-controller ; then
ovs-vsctl --no-wait set-controller br-int tcp:$HOST_IP:6633
run_process df-controller "python $DF_LOCAL_CONTROLLER $HOST_IP $REMOTE_DB_IP"
run_process df-controller "python $DF_LOCAL_CONTROLLER --config-file $NEUTRON_CONF"
fi
}

View File

View File

@ -0,0 +1,31 @@
# 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.
from oslo_config import cfg
df_opts = [
cfg.StrOpt('remote_db_ip',
default='127.0.0.1',
help=_('The remote db server ip address')),
cfg.IntOpt('remote_db_port',
default=4001,
help=_('The remote db server port')),
cfg.StrOpt('nb_db_class',
default='dragonflow.db.drivers.etcd_nb_impl.EtcdNbApi',
help=_('The driver class for the NB DB')),
cfg.StrOpt('local_ip',
default='127.0.0.1',
help=_('Local host IP')),
cfg.StrOpt('tunnel_type',
default='geneve',
help=_('The encapsulation type for the tunnel')),
]

View File

@ -18,30 +18,35 @@ import sys
import time
import eventlet
from oslo_config import cfg
from oslo_log import log
from oslo_utils import importutils
from neutron.agent.common import config
from neutron.common import config as common_config
from neutron.i18n import _LE
from ryu.base.app_manager import AppManager
from ryu.controller.ofp_handler import OFPHandler
from dragonflow.common import common_params
from dragonflow.controller.l2_app import L2App
from dragonflow.controller.l3_app import L3App
from dragonflow.db import db_store
from dragonflow.db.drivers import ovsdb_vswitch_impl
from dragonflow.db.drivers import etcd_nb_impl
config.setup_logging()
LOG = log.getLogger("dragonflow.controller.df_local_controller")
eventlet.monkey_patch()
cfg.CONF.register_opts(common_params.df_opts, 'df')
class DfLocalController(object):
def __init__(self, chassis_name, ip, remote_db_ip):
def __init__(self, chassis_name):
self.l3_app = None
self.l2_app = None
self.open_flow_app = None
@ -50,14 +55,15 @@ class DfLocalController(object):
self.nb_api = None
self.vswitch_api = None
self.chassis_name = chassis_name
self.ip = ip
self.remote_db_ip = remote_db_ip
self.ip = cfg.CONF.df.local_ip
self.tunnel_type = cfg.CONF.df.tunnel_type
self.sync_finished = False
def run(self):
#self.nb_api = ovsdb_nb_impl.OvsdbNbApi(self.remote_db_ip)
self.nb_api = etcd_nb_impl.EtcdNbApi(self.remote_db_ip)
self.nb_api.initialize()
nb_class = importutils.import_class(cfg.CONF.df.nb_db_class)
self.nb_api = nb_class()
self.nb_api.initialize(db_ip=cfg.CONF.df.remote_db_ip,
db_port=cfg.CONF.df.remote_db_port)
self.vswitch_api = ovsdb_vswitch_impl.OvsdbSwitchApi(self.ip)
self.vswitch_api.initialize()
@ -188,7 +194,7 @@ class DfLocalController(object):
if chassis is None:
self.nb_api.add_chassis(self.chassis_name,
self.ip,
'geneve')
self.tunnel_type)
def create_tunnels(self):
tunnel_ports = {}
@ -271,9 +277,8 @@ class DfLocalController(object):
# <local ip address> <southbound_db_ip_address>
def main():
chassis_name = socket.gethostname()
ip = sys.argv[1] # local ip '10.100.100.4'
remote_db_ip = sys.argv[2] # remote SB DB IP '10.100.100.4'
controller = DfLocalController(chassis_name, ip, remote_db_ip)
common_config.init(sys.argv[1:])
controller = DfLocalController(chassis_name)
controller.run()
if __name__ == "__main__":

View File

@ -17,7 +17,7 @@
class NbApi(object):
def initialize(self):
def initialize(self, db_ip, db_port):
pass
def sync(self):

View File

@ -23,16 +23,14 @@ from dragonflow.db import api_nb
class EtcdNbApi(api_nb.NbApi):
def __init__(self, db_ip='127.0.0.1', db_port=4001):
def __init__(self):
super(EtcdNbApi, self).__init__()
self.client = None
self.ip = db_ip
self.port = db_port
self.current_key = 0
self.controller = None
def initialize(self):
self.client = etcd.Client(host=self.ip, port=self.port)
def initialize(self, db_ip='127.0.0.1', db_port=4001):
self.client = etcd.Client(host=db_ip, port=db_port)
def support_publish_subscribe(self):
return True

View File

@ -47,23 +47,16 @@ from neutron.db import l3_db
from neutron.db import l3_gwmode_db
from neutron.db import portbindings_db
from neutron.db import securitygroups_db
from neutron.i18n import _LE, _LI
from neutron.i18n import _, _LE, _LI
from dragonflow.db.drivers import etcd_nb_impl
from dragonflow.common import common_params
from dragonflow.neutron.common import constants as ovn_const
from dragonflow.neutron.common import utils
df_opts = [
cfg.StrOpt('remote_db_ip',
default='127.0.0.1',
help=_('The remote db ip address')),
]
cfg.CONF.register_opts(df_opts, 'df')
LOG = log.getLogger(__name__)
cfg.CONF.register_opts(common_params.df_opts, 'df')
class DFPlugin(db_base_plugin_v2.NeutronDbPluginV2,
securitygroups_db.SecurityGroupDbMixin,
@ -95,8 +88,10 @@ class DFPlugin(db_base_plugin_v2.NeutronDbPluginV2,
# instead of using the hybrid mode.
self.vif_details = {portbindings.CAP_PORT_FILTER: True}
self.nb_api = etcd_nb_impl.EtcdNbApi(db_ip=cfg.CONF.df.remote_db_ip)
self.nb_api.initialize()
nb_class = importutils.import_class(cfg.CONF.df.nb_db_class)
self.nb_api = nb_class()
self.nb_api.initialize(db_ip=cfg.CONF.df.remote_db_ip,
db_port=cfg.CONF.df.remote_db_port)
self.global_id = self._find_current_global_id()
self.base_binding_dict = {
@ -113,9 +108,12 @@ class DFPlugin(db_base_plugin_v2.NeutronDbPluginV2,
# and continue to allocate starting from it, we still need to handle
# the case of wrap up in the id's
max_id = 0
for port in self.nb_api.get_all_logical_ports():
if port.get_tunnel_key() > max_id:
max_id = port.get_tunnel_key()
try:
for port in self.nb_api.get_all_logical_ports():
if port.get_tunnel_key() > max_id:
max_id = port.get_tunnel_key()
except Exception:
pass
return max_id
def _setup_rpc(self):