鑒於不知道Neutron的人也不會看這篇文章,而知道的人也不用我再啰嗦Neutron是什么東西,我決定跳過Neutron簡介,直接爆料。
首先要介紹一下我的開發環境。我沒有使用DevStack,而是直接在電腦上安裝了三個Virtual Box,然后根據OpenStack的Ubuntu 安裝指南部署了一個環境:一個控制節點,一個網絡節點和一個計算節點。接下來我會直接在控制節點上修改 <your path>/neutron/ 下面的文件,然后通過重啟neutron 的各個service來更新我的修改。如果使用DevStack的話估計和我的情況也差不太多。
那我的neutron在安裝完之后的完整路徑是 /usr/lib/python2.7/dist-packages/neutron。neutron下的文件結構如下:
- neutron/ - agent/ - api/ - cmd/ - common/ - db/ - debug/ - extensions/ - locale/ - notifiers/ - openstack/ - plugins/ - scheduler/ - server/ - services/ - manager.py - neutron_plugin_base_v2.py - service.py - wsgi.py - ...
其中,自己寫的plugin就會放在plugins/ 下面,而neutron_plugin_base_v2.py中定義了一個plugin應該實現的最小的API集合。其他還有一些在extensions/ 和db/ 下面的文件也比較重要,會在接下來的一些文章中提到。最后省略了一些目前我沒有特別用到的文件。
如果有人對Neutron如何加載plugin感興趣,可以再manager.py中加一些斷點用pdb進行debug。它里面有一個class叫NeutronManager, 在初始化過程中有一個語句加載了plugin:plugin_provider = cfg.CONF.core_plugin。具體debug方法可以參考Yong Sheng Gong的一個ppt,鏈接在這里:http://www.slideshare.net/gongys2004/inside-neutron-2
好,現在我們就要開始實現自己的plugin了。
第一步就是在plugins下面創建自己的文件夾和一些文件:
- neutron - plugins - myplugin - __init__.py - plugin.py
上述兩個文件是最基本的,當然plugin.py也可以用不同的名字。但是__init__.py的名字是不能改的,這個用來告訴Python myplugin可以看做是一個module。plugin.py里面可以先定義一個基本空的class 叫做MyPlugin,雖然現在這個plugin什么用都沒有。
from neutron.db import db_base_plugin_v2 from neutron.openstack.common import log LOG = log.getLogger(__name__) class MyPlugin(db_base_plugin_v2.NeutronDbPluginV2): def __init__(self): LOG.info("MyPlugin is started.")
代碼中出現的 neutron.db 和 neutron.openstack.common 我會在之后的章節中提到。現在暫時不用去管它們。
第二步,搞定plugin.py之后就要想辦法在Neutron里注冊一下這個plugin,這樣Neutron啟動的時候就會認識這個plugin並且知道怎么加載它。這時候需要找到一個entry_points.txt文件。它不在之前我們提到的那個neutron大文件夾下面,而是在與之平行的一個neutron egg info 文件夾下。具體在我的環境中:
- neutron - neutron-2014.1.egg-info - entry_points.txt
在這個文件中,有一個選項是[neutron.core_plugins],所有的注冊的core_plugins都在里面。在它下面我們可以自己加一行:
myplugin = neutron.plugins.myplugin.plugin:MyPlugin
然后在 /etc/neutron/neturon.conf 中有一個選項是[DEFAULT],在它下面有一行用來設置core plugin:
core_plugin = myplugin
如果沒有找到entry_points.txt這個文件的話,據說另外一個辦法就是直接在 neutron.conf 中指明這個plugin:
core_plugin = neutron.plugins.myplugin.plugin.MyPlugin
不過這個方法我沒有嘗試過。
做完這兩步之后再重啟一下neutron就搞定收工了。看一下/var/log/neutron/server.log,如果出現了我們那行log信息的話就說明Neutron已經加載了我們的什么都干不了的plugin了。
那么plugin具體是怎么實現的呢?請看下回分解。