我们运行ryu应用使用如下命令
ryu-manager <app-path>
ryu-manager调用的是ryu/cmd/manager.py中的main()方法,下面我们看下manager.py文件
首先是配置项的定义与注册,若对CONF不了解,请先学习ryu源码分析准备oslo库
CONF.register_cli_opts([ cfg.ListOpt('app-lists', default=[], help='application module name to run'), cfg.MultiStrOpt('app', positional=True, default=[], help='application module name to run'), cfg.StrOpt('pid-file', default=None, help='pid file name'), cfg.BoolOpt('enable-debugger', default=False, help='don\'t overwrite Python standard threading library' '(use only for debugging)'), ])
上述代码定义了各个配置项的属性,如ListOpt,MultiStrOpt,StrOpt,BoolOpt
其中属性为ListOpt 与 MultiStrOpt返回的都为列表形式
紧接着是main()函数中的代码,
根据配置项的注册,读取配置文件/usr/loca/etc/ryu/ryu.conf的配置
try: CONF(args=args, prog=prog, project='ryu', version='ryu-manager %s' % version, default_config_files=['/usr/local/etc/ryu/ryu.conf']) except cfg.ConfigFilesNotFoundError: CONF(args=args, prog=prog, project='ryu', version='ryu-manager %s' % version)
根据配置文件的配置执行 log、pidfile
if CONF.enable_debugger: LOG = logging.getLogger('ryu.cmd.manager') msg = 'debugging is available (--enable-debugger option is turned on)' LOG.info(msg) else: hub.patch(thread=True) if CONF.pid_file: import os with open(CONF.pid_file, 'w') as pid_file: pid_file.write(str(os.getpid()))
然后启动applist中的应用,若果applist为空,则启动ofp_handler应用
app_lists = CONF.app_lists + CONF.app # keep old behaivor, run ofp if no application is specified. if not app_lists: app_lists = ['ryu.controller.ofp_handler'] app_mgr = AppManager.get_instance() app_mgr.load_apps(app_lists) contexts = app_mgr.create_contexts() services = [] services.extend(app_mgr.instantiate_apps(**contexts)) webapp = wsgi.start_service(app_mgr) if webapp: thr = hub.spawn(webapp) services.append(thr) try: hub.joinall(services) finally: app_mgr.close()
从上面代码可以看出,
首先实例化一个AppManager对象(AppManager.get_instance())
然后加载应用app_lists
接着调用create_contexts()函数,创建对用的contexts(返回字典形式),
然后调用instantiate_apps函数将app_list和context中的app均实例化。
启动wsgi架构,提供web应用。最后将所有的应用作为任务,作为coroutine的task去执行,joinall使得程序必须等待所有的task都执行完成才可以退出程序。
最后调用close函数,关闭程序,释放资源。