ryu 源码分析之manager

我们运行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函数,关闭程序,释放资源。

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
永久连接: http://www.nfvschool.cn/?p=612
标签:

发表评论