1. 程式人生 > >openstack neutron學習(一) ---- neutron-server入口

openstack neutron學習(一) ---- neutron-server入口

宣告:

本部落格歡迎轉發,但請保留原作者資訊!

內容系本人學習、研究和總結,如有雷同,不勝榮幸!

參考資料

通過devstack啟動neutron服務的配置

通過devstack啟動neutron服務需要在localrc中加入如下配置:
disable_service n-net
enable_service q-svc
enable_service q-agt
enable_service q-dhcp
enable_service q-l3
enable_service q-meta
enable_service neutron
# Optional, to enable tempest configuration as part of devstack
enable_service tempest
然後再執行stack.sh

neutron-server入口

main函式

cat /usr/local/bin/neutron-server,其內容為:

import sys
from neutron.server import main

if __name__ == "__main__":
    sys.exit(main())

很容易看出執行的入口為neutron.server.main函式,neutron.server.main函式程式碼如下:

def main():
    eventlet.monkey_patch()               

    # the configuration will be read into the cfg.CONF global data structure
    config.parse(sys.argv[1:])
    if not cfg.CONF.config_file:
        sys.exit(_("ERROR: Unable to find configuration file via the default"
                   " search paths (~/.neutron/, ~/, /etc/neutron/, /etc/) and"
                   " the '--config-file' option!"))
    try:
        neutron_service = service.serve_wsgi(service.NeutronApiService)       # 建立NeutronApiService的例項,並呼叫start方法。start方法就是啟動socket伺服器端


        neutron_service.wait()
    except RuntimeError as e:
        sys.exit(_("ERROR: %s") % e)

start函式以協程方式啟動wsgi服務的程式碼:

def _run(self, application, socket):
        """Start a WSGI server in a new green thread."""
        eventlet.wsgi.server(socket, application, custom_pool=self.pool,
                             log=logging.WritableLogger(LOG))                                      # eventlet.wsgi.server()生成了一個http server,並通過server.start()啟動了一個WSGI程式。WSGI(web server gateway interface)web伺服器閘道器介面,WSGI的作用就是將client發給web server的請求轉發給要實際處理這個請求的程式。

app入口

處理請求的app為函式_run_wsgi中的 app = config.load_paste_app(app_name),該函式的實現就是從配置檔案api-paste.ini中載入‘neutron’的app。

api-paste.ini中根據不同版本構建不同的例項:

[composite:neutron]
use = egg:Paste#urlmap
/: neutronversions
/v2.0: neutronapi_v2_0

[composite:neutronapi_v2_0]
use = call:neutron.auth:pipeline_factory
noauth = extensions neutronapiapp_v2_0
keystone = authtoken keystonecontext extensions neutronapiapp_v2_0

[filter:keystonecontext]
paste.filter_factory = neutron.auth:NeutronKeystoneContext.factory

[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory

[filter:extensions]
paste.filter_factory = neutron.api.extensions:plugin_aware_extension_middleware_factory

[app:neutronversions]
paste.app_factory = neutron.api.versions:Versions.factory

[app:neutronapiapp_v2_0]
paste.app_factory = neutron.api.v2.router:APIRouter.factory

neutron.api.v2.router:APIRouter.factory就是構造APIRouter的例項,APIRouter的建構函式中構造了4個controller,程式碼如:

mapper.connect('index', '/', controller=Index(RESOURCES))

controller = base.create_resource(
                collection, resource, plugin, params, allow_bulk=allow_bulk,
                parent=parent, allow_pagination=allow_pagination,
                allow_sorting=allow_sorting)

base.create_resource中將處理函式記錄到self._plugin_handlers,內容如下:

{'create': 'create_subnet', 'delete': 'delete_subnet', 'list': 'get_subnets', 'update': 'update_subnet', 'show': 'get_subnet'}

{'create': 'create_network', 'delete': 'delete_network', 'list': 'get_networks', 'update': 'update_network', 'show': 'get_network'}

{'create': 'create_port', 'delete': 'delete_port', 'list': 'get_ports', 'update': 'update_port', 'show': 'get_port'}

擴充套件的入口為(api-paste.ini配置中指定):neutron.api.extensions:plugin_aware_extension_middleware_factory,

{'create': 'create_router', 'delete': 'delete_router', 'list': 'get_routers', 'update': 'update_router', 'show': 'get_router'}

{'create': 'create_floatingip', 'delete': 'delete_floatingip', 'list': 'get_floatingips', 'update': 'update_floatingip', 'show': 'get_floatingip'}

{'create': 'create_agent', 'delete': 'delete_agent', 'list': 'get_agents', 'update': 'update_agent', 'show': 'get_agent'}

通過這些操作和函式對應的記錄,將相應的請求路由到配置的plugin的相應函式。

controller = base.create_resource中建立了Controller物件,其中的index方法就是處理wsgi的查詢列表請求,show就是處理根據指定id獲取單個資訊的請求,create就是建立,delete就是刪除,update就是更新。在每一個方法中呼叫plugin的相應方法來處理請求訊息。

/etc/neutron/neutron.conf中使用的預設plugin為:core_plugin = neutron.plugins.ml2.plugin.Ml2Plugin

db本身也是一個plugin,名字為db_base_plugin_v2.py。