#Sora#openstack基礎庫stevedore試用總結



什麼是stevedore?html

stevedore是創建在setuptools的entry point的功能上的,用於python程序動態加載代碼,在openstack中被多個組件使用:好比ceilometer,neutron的plugin。固然,你能夠直接使用python

python的某些黑魔法實現插件的加載,但太原始了。stevedore基於entry point提供了更高層次的封裝。linux

stevedore的官方文檔在此:http://docs.openstack.org/developer/stevedore/ web

學習和入門setuptools:http://www.360doc.com/content/14/0306/11/13084517_358166737.shtml sql

官方文檔的部分翻譯:http://www.360doc.com/content/14/0429/19/9482_373285413.shtml docker

來自華爲孔令賢(源地址非該人博客)的setup.py詳解:http://blog.sina.com.cn/s/blog_4951301d0101etvj.html json



偶計劃在sora項目中引入stevedore與oslo.config簡化某些開發的組件,先是測試了stevedore,寫了個簡單的scheduler插件websocket

環境準備:
dom

安裝stevedore庫,及組織相關目錄python2.7

pip install stevedore
mkdir sora
cd sora
mkdir scheduler  #scheduler在sora目錄中

構建這樣一個目錄樹:


步驟:

建立一個抽象類scheduler,新的plugin要繼承scheduler並重寫相關方法scheduler

#sora/scheduler/base.py
import abc

class scheduler(object):
   __metaclass__ = abc.ABCMeta

   @abc.abstractmethod
   def scheduler(self,data):
       pass


繼承base類建立插件simple與memory

#sora/scheduler/memory.py
import base
class memoryscheduler(base.scheduler):
  def scheduler(self,data):
      id = data[max(data['memory'])]
      return id
#sora/scheduler/simple.py
import base
import random
class simplescheduler(base.scheduler):
  def scheduler(self,data):
      id = data[random.choice(data['memory'])]
      return id

simple插件是隨機選擇一個節點id,而memory則選擇內存剩餘最多的節點id


編寫setup.py

#sora/setup.py
from setuptools import setup, find_packages
setup(
    name='sora-scheduler',
    version='1.0',
    description='sora.scheduler',
    author='hochikong',
    author_email='hochikong',
    platforms=['Any'],
    scripts=[],
   # provides=['sora.scheduler',
   #           ],
    packages=find_packages(),
    include_package_data=True,
    entry_points={
        'sora.scheduler': [
            'memorybase = scheduler.memory:memoryscheduler',
            'randombase = scheduler.simple:simplescheduler',
        ],
    },
    zip_safe=False,
)


安裝本身編寫的包:

root@workgroup1:~/sora# python setup.py install
running install
running bdist_egg
running egg_info
creating sora_scheduler.egg-info
writing sora_scheduler.egg-info/PKG-INFO
writing top-level names to sora_scheduler.egg-info/top_level.txt
writing dependency_links to sora_scheduler.egg-info/dependency_links.txt
writing entry points to sora_scheduler.egg-info/entry_points.txt
writing manifest file 'sora_scheduler.egg-info/SOURCES.txt'
reading manifest file 'sora_scheduler.egg-info/SOURCES.txt'
writing manifest file 'sora_scheduler.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/scheduler
copying scheduler/__init__.py -> build/lib.linux-x86_64-2.7/scheduler
copying scheduler/base.py -> build/lib.linux-x86_64-2.7/scheduler
copying scheduler/memory.py -> build/lib.linux-x86_64-2.7/scheduler
copying scheduler/simple.py -> build/lib.linux-x86_64-2.7/scheduler
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/scheduler
copying build/lib.linux-x86_64-2.7/scheduler/__init__.py -> build/bdist.linux-x86_64/egg/scheduler
copying build/lib.linux-x86_64-2.7/scheduler/base.py -> build/bdist.linux-x86_64/egg/scheduler
copying build/lib.linux-x86_64-2.7/scheduler/memory.py -> build/bdist.linux-x86_64/egg/scheduler
copying build/lib.linux-x86_64-2.7/scheduler/simple.py -> build/bdist.linux-x86_64/egg/scheduler
byte-compiling build/bdist.linux-x86_64/egg/scheduler/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-x86_64/egg/scheduler/base.py to base.pyc
byte-compiling build/bdist.linux-x86_64/egg/scheduler/memory.py to memory.pyc
byte-compiling build/bdist.linux-x86_64/egg/scheduler/simple.py to simple.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying sora_scheduler.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying sora_scheduler.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying sora_scheduler.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying sora_scheduler.egg-info/entry_points.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying sora_scheduler.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO
copying sora_scheduler.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
creating dist
creating 'dist/sora_scheduler-1.0-py2.7.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing sora_scheduler-1.0-py2.7.egg
creating /usr/local/lib/python2.7/dist-packages/sora_scheduler-1.0-py2.7.egg
Extracting sora_scheduler-1.0-py2.7.egg to /usr/local/lib/python2.7/dist-packages
Adding sora-scheduler 1.0 to easy-install.pth file

Installed /usr/local/lib/python2.7/dist-packages/sora_scheduler-1.0-py2.7.egg
Processing dependencies for sora-scheduler==1.0
Finished processing dependencies for sora-scheduler==1.0


嘗試手動加載插件:

root@workgroup1:~/sora# python
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from scheduler.memory import memoryscheduler
>>> dt = {13:'id1',324:'id2',434:'id3','memory':[13,324,434]}
>>> driver = memoryscheduler()
>>> driver.scheduler(dt)
'id3'
>>>

不過手動加載並無太大意義


使用stevedore的drivermanager:

>>> from stevedore import driver
>>> dt = {13:'id1',324:'id2',434:'id3','memory':[13,324,434]}
>>> mgr = driver.DriverManager(
...     namespace='sora.scheduler',
...     name='randombase',
...     invoke_on_load=True,         #設置爲true,即載入後自動實例化插件類,若是是函數,則調用
... )
>>> mgr.driver.scheduler(dt)
'id3'
>>> mgr.driver.scheduler(dt)
'id2'
>>> mgr.driver.scheduler(dt)
'id3'
>>> mgr.driver.scheduler(dt)
'id2'
>>> mgr.driver.scheduler(dt)
'id1'
>>>

這裏我導入了randombase,怎樣調用plugin裏的方法很明顯了


順帶檢查下python中個人包的安裝情況:

root@workgroup1:~# cd /usr/local/lib/python2.7/dist-packages/
root@workgroup1:/usr/local/lib/python2.7/dist-packages# ls
amqp                                           OpenSSL
amqp-1.4.6.dist-info                           pbr
anyjson                                        pbr-1.3.0.dist-info
anyjson-0.3.3.egg-info                         pika
backports                                      pika-0.9.14.egg-info
backports.ssl_match_hostname-3.4.0.2.egg-info  psutil
billiard                                       psutil-2.2.1.egg-info
billiard-3.3.0.19.egg-info                     _psutil_linux.so
_billiard.so                                   _psutil_posix.so
bottle-0.12.8.egg-info                         pymongo
bottle.py                                      pymongo-2.8.egg-info
bottle.pyc                                     pyOpenSSL-0.15.1.dist-info
bson                                           python_etcd-0.3.3.egg-info
celery                                         pytz
celery-3.1.17.dist-info                        pytz-2015.2.dist-info
docker                                         six-1.9.0.dist-info
docker_py-1.0.0.egg-info                       six.py
easy-install.pth                               six.pyc
etcd                                           sora_scheduler-1.0-py2.7.egg
eventlet                                       SQLAlchemy-0.9.9-py2.7-linux-x86_64.egg
eventlet-0.17.1.dist-info                      stevedore
funtests                                       stevedore-1.6.0.dist-info
glances                                        tests
Glances-2.3.egg-info                           virtualenv-12.0.7.dist-info
greenlet-0.4.5.egg-info                        virtualenv.py
greenlet.so                                    virtualenv.pyc
gridfs                                         virtualenv_support
kombu                                          websocket
kombu-3.0.24.dist-info                         websocket_client-0.25.0.egg-info


能夠看到裏面有個sora_scheduler-1.0-py2.7.egg目錄,查看一下:

我不太清楚爲何python在導入scheduler模塊時,並不須要指明sora_scheduler-1.0-py2.7.egg,可能與egg有關,執行import scheduler時,導入的是sora_scheduler-1.0-py2.7.egg目錄下

的scheduler包,一樣的還有SQLAlchemy,有一個SQLAlchemy-0.9.9-py2.7-linux-x86_64.egg,導入時只需執行import sqlalchemy


疑問:

可能有人會問,若是我想添加新的插件要怎麼辦,我想,最好的方法就是修改setup.py,更新安裝一次該包便可


參考:

http://docs.openstack.org/developer/stevedore/

http://www.360doc.com/content/14/0306/11/13084517_358166737.shtml

http://www.360doc.com/content/14/0429/19/9482_373285413.shtml

相關文章
相關標籤/搜索