Separate vswitch_api and ryu from the main logic

The vswitch_api and ryu are specific to ovs and should be removed from
the main code logic.
They are now encapsulated within the df_ovs_driver.
Currently the vswitch is still referenced directly from the driver in
all the tests. This behavior should be removed in a later patch.

Change-Id: Id919faaebece90c1410226d38f28c52af7693c08
Partial-Bug: #1781376
This commit is contained in:
Shachar Snapiri 2018-08-05 17:49:12 +03:00
parent 0f05fc13d7
commit 7f973380b6
15 changed files with 56 additions and 31 deletions

View File

@ -379,10 +379,10 @@ class IPVlanNestedPortArpImpl(IPv4NestedPortMixin, BaseNestedPortImpl):
class TrunkApp(df_base_app.DFlowApp):
def __init__(self, api, vswitch_api=None, nb_api=None,
def __init__(self, api, switch_backend=None, nb_api=None,
neutron_server_notifier=None):
super(TrunkApp, self).__init__(
api, vswitch_api=vswitch_api,
api, switch_backend=switch_backend,
nb_api=nb_api,
neutron_server_notifier=neutron_server_notifier)
# A dispatch table, to add the relevant openflow rules according to

View File

@ -33,11 +33,11 @@ LOG = log.getLogger(__name__)
class DFlowApp(object):
def __init__(self, api, vswitch_api=None, nb_api=None,
def __init__(self, api, switch_backend=None, nb_api=None,
neutron_server_notifier=None):
self.api = api
self.db_store = db_store.get_instance()
self.vswitch_api = vswitch_api
self.switch_backend = switch_backend
self.nb_api = nb_api
self.neutron_server_notifier = neutron_server_notifier
# Though there is nothing to initialize in super class, call it
@ -45,6 +45,10 @@ class DFlowApp(object):
super(DFlowApp, self).__init__()
self._register_events()
@property
def vswitch_api(self):
return self.switch_backend.vswitch_api
def _register_events(self):
'''Iterate all methods we decorated with @register_event and register
them to the requested models.
@ -75,7 +79,7 @@ class DFlowApp(object):
@property
def dfdp(self):
return self.api._new_dp
return self.switch_backend.datapath
@property
def parser(self):

View File

@ -29,6 +29,19 @@ class DfSwitchDriver(object):
self.db_change_callback = db_change_callback
self.neutron_notifier = neutron_notifier
# TODO(snapiri): remove the need for the df_app argument
@abc.abstractmethod
def setup_datapath(self, df_app):
"""Setup the datapath flow
This method needs to be called for every dragonflow application in the
packet flow to initialize its datapath
"""
@property
@abc.abstractmethod
def datapath(self):
"""Returns a datapath object"""
@abc.abstractmethod
def start(self):
"""Start running the switch backend"""

View File

@ -72,7 +72,7 @@ class Datapath(object):
}
)
def set_up(self, ryu_base, vswitch_api, nb_api, notifier):
def set_up(self, ryu_base, switch_backend, nb_api, neutron_notifier):
"""
Instantiate the application classes.
Instantiate the applications (Including table and register allocation)
@ -102,9 +102,9 @@ class Datapath(object):
self.log_datapath_allocation(vertex.name, dp_alloc)
self._dp_allocs[vertex.name] = dp_alloc
app = app_class(api=ryu_base,
vswitch_api=vswitch_api,
switch_backend=switch_backend,
nb_api=nb_api,
neutron_server_notifier=notifier,
neutron_server_notifier=neutron_notifier,
dp_alloc=dp_alloc,
**(vertex.params or {})
)

View File

@ -18,11 +18,13 @@ from ryu.base import app_manager
from ryu import cfg as ryu_cfg
from dragonflow import conf as cfg
from dragonflow.controller import ryu_base_app
from dragonflow.controller import datapath_layout
from dragonflow.db.models import l2
from dragonflow.db.models import switch
from dragonflow.ovsdb import vswitch_impl
from dragonflow.switch.drivers import df_switch_driver
from dragonflow.switch.drivers.ovs import datapath
from dragonflow.switch.drivers.ovs import ryu_base_app
class DfOvsDriver(df_switch_driver.DfSwitchDriver):
@ -34,6 +36,8 @@ class DfOvsDriver(df_switch_driver.DfSwitchDriver):
self.open_flow_app = None
self.open_flow_service = None
self.neutron_notifier = None
self._datapath = datapath.Datapath(
datapath_layout.get_datapath_layout())
def initialize(self, db_change_callback, neutron_notifier):
super(DfOvsDriver, self).initialize(db_change_callback,
@ -41,7 +45,7 @@ class DfOvsDriver(df_switch_driver.DfSwitchDriver):
self.open_flow_app = self.app_mgr.instantiate(
ryu_base_app.RyuDFAdapter,
nb_api=self.nb_api,
vswitch_api=self.vswitch_api,
switch_backend=self,
neutron_server_notifier=self.neutron_notifier,
db_change_callback=self.db_change_callback
)
@ -49,6 +53,14 @@ class DfOvsDriver(df_switch_driver.DfSwitchDriver):
self.open_flow_service = self.app_mgr.instantiate(
of_service.OfctlService)
def setup_datapath(self, df_app):
self._datapath.set_up(df_app, self,
self.nb_api, self.neutron_notifier)
@property
def datapath(self):
return self._datapath
def start(self):
self.vswitch_api.initialize(self.db_change_callback)
# both set_controller and del_controller will delete flows.

View File

@ -27,8 +27,6 @@ from ryu import utils
from dragonflow.common import profiler as df_profiler
from dragonflow.controller.common import constants
from dragonflow.controller import datapath as new_dp
from dragonflow.controller import datapath_layout as new_dp_layout
from dragonflow.controller import dispatcher
@ -39,19 +37,19 @@ class RyuDFAdapter(ofp_handler.OFPHandler):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
OF_AUTO_PORT_DESC_STATS_REQ_VER = 0x04
def __init__(self, vswitch_api, nb_api,
def __init__(self, switch_backend, nb_api,
db_change_callback,
neutron_server_notifier=None):
super(RyuDFAdapter, self).__init__()
self.dispatcher = dispatcher.AppDispatcher(cfg.CONF.df.apps_list)
self.vswitch_api = vswitch_api
self.vswitch_api = switch_backend.vswitch_api
self.nb_api = nb_api
self.switch_backend = switch_backend
self.neutron_server_notifier = neutron_server_notifier
self._datapath = None
self.table_handlers = {}
self.first_connect = True
self.db_change_callback = db_change_callback
self._new_dp = new_dp.Datapath(new_dp_layout.get_datapath_layout())
@property
def datapath(self):
@ -60,7 +58,7 @@ class RyuDFAdapter(ofp_handler.OFPHandler):
def start(self):
super(RyuDFAdapter, self).start()
self.load(self,
vswitch_api=self.vswitch_api,
switch_backend=self.switch_backend,
nb_api=self.nb_api,
neutron_server_notifier=self.neutron_server_notifier)
self.wait_until_ready()
@ -111,9 +109,7 @@ class RyuDFAdapter(ofp_handler.OFPHandler):
self.get_sw_async_msg_config()
self._new_dp.set_up(
self, self.vswitch_api, self.nb_api, self.neutron_server_notifier)
self.switch_backend.setup_datapath(self)
self.dispatcher.dispatch('switch_features_handler', ev)
if not self.first_connect:

View File

@ -21,9 +21,9 @@ from oslo_log import log
from dragonflow.common import utils as df_utils
from dragonflow import conf as cfg
from dragonflow.controller.common import constants as ctrl_const
from dragonflow.controller import datapath
from dragonflow.db import api_nb
from dragonflow.db import db_common
from dragonflow.switch.drivers.ovs import datapath
from dragonflow.tests import base
from dragonflow.tests.common import app_testing_objects as test_objects
from dragonflow.tests.common import clients

View File

@ -20,8 +20,8 @@ from ryu.base import app_manager
from ryu import cfg as ryu_cfg
from dragonflow import conf as cfg
from dragonflow.controller import ryu_base_app
from dragonflow.ovsdb import vswitch_impl
from dragonflow.switch.drivers.ovs import ryu_base_app
from dragonflow.tests.common import constants as const
from dragonflow.tests.fullstack import test_base
@ -35,7 +35,7 @@ class TestRyuBaseApp(test_base.DFTestBase):
app_mgr = app_manager.AppManager.get_instance()
self.open_flow_app = app_mgr.instantiate(
ryu_base_app.RyuDFAdapter,
vswitch_api=mock.Mock(),
switch_backend=mock.Mock(),
nb_api=mock.Mock(),
db_change_callback=self._db_change_callback)
self.open_flow_app.load = mock.Mock()

View File

@ -21,10 +21,8 @@ from oslo_config import cfg
from oslo_log import fixture as log_fixture
from dragonflow.common import constants
from dragonflow.controller import datapath
from dragonflow.controller import datapath_layout
from dragonflow.controller import df_local_controller
from dragonflow.controller import ryu_base_app
from dragonflow.controller import topology
from dragonflow.db import api_nb
from dragonflow.db import db_store
@ -34,6 +32,8 @@ from dragonflow.db.models import l2
from dragonflow.db.models import l3
from dragonflow.db.models import secgroups
from dragonflow.db.models import switch
from dragonflow.switch.drivers.ovs import datapath
from dragonflow.switch.drivers.ovs import ryu_base_app
from dragonflow.tests import base as tests_base
@ -87,7 +87,7 @@ class DFAppTestBase(tests_base.BaseTestCase):
self.vswitch_api = switch_backend.vswitch_api = mock.MagicMock()
kwargs = dict(
nb_api=self.controller.nb_api,
vswitch_api=self.vswitch_api
switch_backend=switch_backend
)
switch_backend.open_flow_app = ryu_base_app.RyuDFAdapter(
db_change_callback=self.controller.db_change_callback,

View File

@ -15,8 +15,8 @@ import mock
import testscenarios
from dragonflow.controller import app_base
from dragonflow.controller import datapath
from dragonflow.controller import datapath_layout
from dragonflow.switch.drivers.ovs import datapath
from dragonflow.tests import base as tests_base
load_tests = testscenarios.load_tests_apply_scenarios

View File

@ -14,12 +14,12 @@ import mock
from oslo_config import cfg
from dragonflow.controller import df_local_controller
from dragonflow.controller import ryu_base_app
from dragonflow.db import db_store
from dragonflow.db import field_types as df_fields
from dragonflow.db import model_framework
from dragonflow.db.models import core
from dragonflow.db.models import mixins
from dragonflow.switch.drivers.ovs import ryu_base_app
from dragonflow.tests.common import utils
from dragonflow.tests.unit import test_app_base

View File

@ -326,7 +326,7 @@ class TestModelFramework(tests_base.BaseTestCase):
TestApp(
api=mock.MagicMock(),
vswitch_api=mock.MagicMock(),
switch_backend=mock.MagicMock(),
nb_api=mock.MagicMock(),
)

View File

@ -17,7 +17,7 @@ import mock
import testtools
from dragonflow import conf as cfg
from dragonflow.controller import ryu_base_app
from dragonflow.switch.drivers.ovs import ryu_base_app
from dragonflow.tests import base as tests_base
@ -36,7 +36,7 @@ class TestRyuDFAdapter(tests_base.BaseTestCase):
group='df',
)
self.ryu_df_adapter = ryu_base_app.RyuDFAdapter(
vswitch_api=mock.Mock(),
switch_backend=mock.Mock(),
nb_api=mock.Mock(),
db_change_callback=mock.Mock())
self.mock_app = mock.Mock(spec=[

View File

@ -75,7 +75,7 @@ dragonflow.nb_db_driver =
dragonflow.neutron_notifier_driver =
nb_api_neutron_notifier_driver = dragonflow.db.pubsub_drivers.nb_api_neutron_notifier:NbApiNeutronNotifier
dragonflow.switch_backend_driver =
vswitch_backend_driver = dragonflow.switch.drivers.df_ovs_driver:DfOvsDriver
vswitch_backend_driver = dragonflow.switch.drivers.ovs.df_ovs_driver:DfOvsDriver
neutron.service_plugins =
df-l3-agentless = dragonflow.neutron.services.l3_router_plugin:DFL3AgentlessRouterPlugin
df-l3 = dragonflow.neutron.services.l3_router_plugin:DFL3RouterPlugin