1 什么是Paste Deployment
Paste Deployment是一种机制或者说是一种设计模式,它用于在应用WSGI Application和Server提供一个联系的桥梁,并且为用户提供一个接口,当配置好Paste Deployment之后,用户只需调用loadapp方法就可以使用现有的WSGI Application,而保持了WSGI Application对用户的透明性。
2 Paste Deployment中section简单描述
在paste deploy中,为了区分不同类型的Application,设计了若干种不同类型的section,下面分别进行简单的介绍(参考文献:):
(1)[app:name]
app section直接或间接地定义了一个符合wsgi协议的应用Application,有几种使用方法:
#指向另外一个配置文件中的Application
[app:myapp]
use = config:another_config_file.ini
#指向一个URL
[app:myotherapp]
use = egg:MyApp
#指向一个从指定模块可调用的Application
[app:mythirdapp]
use = call:my.project:myapplication
#指向其他已经定义或即将定义的section
[app:myfourthapp]
use = myotherapp
#直接指向具体的python代码(在cinder中,应用的就是这种定义的section方式)
[app:myfifthapp]
paste.app_factory = myapp.modulename:app_factor
(2)[composite:name]
composite section也定义了一个Application,表示需要将一个请求调度定向(dispatched)到多个,或者多种应用上。composite section可以是wsgi Application的集合,可以包括其他Application section中定义的Application,最常用的用法是:
[composite:osapi_volume]
use = call:cinder.api:root_app_factory
/: apiversions
/v1: openstack_volume_api_v1
/v2: openstack_volume_api_v2
[composite:openstack_volume_api_v1]
use = call:cinder.api.middleware.auth:pipeline_factory
noauth = faultwrap sizelimit noauth apiv1
keystone = faultwrap sizelimit authtoken keystonecontext apiv1
keystone_nolimit = faultwrap sizelimit authtoken keystonecontext apiv1
[composite:openstack_volume_api_v2]
use = call:cinder.api.middleware.auth:pipeline_factory
noauth = faultwrap sizelimit noauth apiv2
keystone = faultwrap sizelimit authtoken keystonecontext apiv2
keystone_nolimit = faultwrap sizelimit authtoken keystonecontext apiv2
(3)[filter:name]
filter section定义了一个过滤器,这里过滤器的意思是,过滤器接受一个Application参数作为对象,并返回一个封装后的Application。我会在稍后的示例中,举出实例来进行解释。
(4)[filter-app:name]
filter-app section定义的也是一个过滤器,这个过滤器直接作用于Application之上。filter-app section表明希望对某个Application进行包装,需要包装的Application通过参数next指明。例如:
[filter-app:blog]
use = egg:Authentication
next = blogapp
这个字段表明在正式调用blogapp之前,先会调用egg:Authentication进行一个用户的验证,随后才会调用blogapp进行处理,这也就实现了对blogapp的一个包装操作。
(5)[pipeline:name]
当使用多个filter的时候需要使用pipeline的方式,它需要提供一个key参数pipeline,后面的值是一个列表,最后以应用结尾。如下:
[pipeline:main]
pipeline = filter1 egg:FilterEgg#filter2 filter3 app
[filter:filter1]
...
假设在ini文件中, 某条pipeline的顺序是filter1, filter2, filter3,app, 那么,最终运行的app_real是这样组织的: app_real = filter1(filter2(filter3(app)))。
在app真正被调用的过程中,filter1.__call__(environ,start_response)被首先调用,若某种检查未通过,filter1做出反应;否则交给filter2.__call__(environ,start_response)进一步处理,若某种检查未通过,filter2做出反应,中断链条,否则交给filter3.__call__(environ,start_response)处理,若filter3的某种检查都通过了,最后交给app.__call__(environ,start_response)进行处理。