summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ryu/base/app_manager.py25
-rwxr-xr-xryu/cmd/manager.py11
-rw-r--r--ryu/controller/controller.py6
-rw-r--r--ryu/controller/handler.py24
-rw-r--r--ryu/controller/ofp_event.py4
5 files changed, 54 insertions, 16 deletions
diff --git a/ryu/base/app_manager.py b/ryu/base/app_manager.py
index b39d6cc2..a5f1c4cf 100644
--- a/ryu/base/app_manager.py
+++ b/ryu/base/app_manager.py
@@ -17,9 +17,10 @@
import inspect
import itertools
import logging
+import sys
from ryu import utils
-from ryu.controller.handler import register_instance
+from ryu.controller.handler import register_instance, get_dependent_services
from ryu.controller.controller import Datapath
from ryu.controller.event import EventRequestBase, EventReplyBase
from ryu.lib import hub
@@ -158,15 +159,13 @@ class AppManager(object):
return None
def load_apps(self, app_lists):
- for app_cls_name in itertools.chain.from_iterable([app_list.split(',')
- for app_list
- in app_lists]):
- LOG.info('loading app %s', app_cls_name)
+ app_lists = [app for app
+ in itertools.chain.from_iterable(app.split(',')
+ for app in app_lists)]
+ while len(app_lists) > 0:
+ app_cls_name = app_lists.pop(0)
- # for now, only single instance of a given module
- # Do we need to support multiple instances?
- # Yes, maybe for slicing.
- assert app_cls_name not in self.applications_cls
+ LOG.info('loading app %s', app_cls_name)
cls = self.load_app(app_cls_name)
if cls is None:
@@ -174,10 +173,18 @@ class AppManager(object):
self.applications_cls[app_cls_name] = cls
+ services = []
for key, context_cls in cls.context_iteritems():
cls = self.contexts_cls.setdefault(key, context_cls)
assert cls == context_cls
+ if issubclass(context_cls, RyuApp):
+ services.extend(get_dependent_services(context_cls))
+
+ services.extend(get_dependent_services(cls))
+ if services:
+ app_lists.extend(services)
+
def create_contexts(self):
for key, cls in self.contexts_cls.items():
context = cls()
diff --git a/ryu/cmd/manager.py b/ryu/cmd/manager.py
index cc1ea747..83867054 100755
--- a/ryu/cmd/manager.py
+++ b/ryu/cmd/manager.py
@@ -61,8 +61,7 @@ def main():
log.init_log()
- # always enable ofp for now.
- app_lists = CONF.app_lists + CONF.app + ['ryu.controller.ofp_handler']
+ app_lists = CONF.app_lists + CONF.app
app_mgr = AppManager()
app_mgr.load_apps(app_lists)
@@ -71,9 +70,11 @@ def main():
services = []
- ctlr = controller.OpenFlowController()
- thr = hub.spawn(ctlr)
- services.append(thr)
+ # TODO: do the following in app_manager's instantiate_apps()
+ ofpapp = controller.start_service(app_mgr)
+ if ofpapp:
+ thr = hub.spawn(ofpapp)
+ services.append(thr)
webapp = wsgi.start_service(app_mgr)
if webapp:
diff --git a/ryu/controller/controller.py b/ryu/controller/controller.py
index d6bc3def..fc6e1168 100644
--- a/ryu/controller/controller.py
+++ b/ryu/controller/controller.py
@@ -321,3 +321,9 @@ def datapath_connection_factory(socket, address):
dpid_str = dpid_to_str(datapath.id)
LOG.error("Error in the datapath %s from %s", dpid_str, address)
raise
+
+
+def start_service(app_mgr):
+ for app in app_mgr.applications:
+ if app.endswith('ofp_handler'):
+ return OpenFlowController()
diff --git a/ryu/controller/handler.py b/ryu/controller/handler.py
index ba45b0dc..d5f57cda 100644
--- a/ryu/controller/handler.py
+++ b/ryu/controller/handler.py
@@ -16,8 +16,7 @@
import inspect
import logging
-
-from ryu.controller import ofp_event
+import sys
LOG = logging.getLogger('ryu.controller.handler')
@@ -63,3 +62,24 @@ def register_instance(i):
# LOG.debug('instance %s k %s m %s', i, _k, m)
if _is_ev_cls(m):
i.register_handler(m.ev_cls, m)
+
+
+def get_dependent_services(cls):
+ services = []
+ for _k, m in inspect.getmembers(cls, inspect.ismethod):
+ if _is_ev_cls(m):
+ service = getattr(sys.modules[m.ev_cls.__module__],
+ '_SERVICE_NAME', None)
+ if service:
+ # avoid cls that registers the own events (like ofp_handler)
+ if cls.__module__ != service:
+ services.append(service)
+
+ services = list(set(services))
+ return services
+
+
+def register_service(service):
+ frm = inspect.stack()[1]
+ m = inspect.getmodule(frm[0])
+ m._SERVICE_NAME = service
diff --git a/ryu/controller/ofp_event.py b/ryu/controller/ofp_event.py
index 566b834d..124a93e7 100644
--- a/ryu/controller/ofp_event.py
+++ b/ryu/controller/ofp_event.py
@@ -16,6 +16,7 @@
import inspect
+from ryu.controller import handler
from ryu import ofproto
from ryu import utils
from . import event
@@ -75,3 +76,6 @@ class EventOFPStateChange(event.EventBase):
def __init__(self, dp):
super(EventOFPStateChange, self).__init__()
self.datapath = dp
+
+
+handler.register_service('ryu.controller.ofp_handler')