在cinder中增加个控制器和API,通过cinderclient测试

在cinder中增加控制器和API

 

增加API:newctrltest

增加API:newctrllist

 

API:

Method

URI

Cmd

POST

/v2/{tenant_id}/newctrls

cinder --os-volume-api-version=2 newctrltest string='test string'

GET

/v2/{tenant_id}/newctrls/detail

cinder --os-volume-api-version=2 newctrllist

 

API:POST  /v2/{tenant_id}/newctrls

cinder --debug --os-volume-api-version=2 newctrlteststring='test string'

 

debug info:

DEBUG:keystoneclient.session:REQ:

curl -g -i -X POSThttp://ubuntu:8776/v2/949fd9b6d22a4bf8b65d9efd78b8d3c2/newctrls -H"User-Agent: python-cinderclient" -H "Content-Type:application/json" -H "Accept: application/json" -H"X-Auth-Token: {SHA1}cc80972a8f99f01be5c9ecb5299d9ea6fd0e0556" -d'{"string": "string=string"}'

 

API:GET /v2/{tenant_id}/newctrls/detail

DEBUG:keystoneclient.session:REQ: curl -g-i -X GEThttp://ubuntu:8776/v2/949fd9b6d22a4bf8b65d9efd78b8d3c2/newctrls/detail -H"User-Agent: python-cinderclient" -H "Accept: application/json"-H "X-Auth-Token: {SHA1}f681de6860b26c5b730a60ccf45d04b4fb9fc858"


 

1.   代码修改之cinderclient

Cinderclient:

(1)      在cinderclient/v2/shell.py中添加do_newctrltest功能

@utils.arg('string',metavar='<string>',
           help='String input for new controller test.')
@utils.service_type('volumev2')
def do_newctrltest(cs, args):
    """NewControllertest."""
   
string = args.string
    cs.newctrl.newctrltest(string)

(2)      在v2/client.py中增加:

from cinderclient.v2 import netcrtl

 

self.newctrl = newctrl.NewctrlManager(self)

(3)      在v2中增加newctrl.py文件

……
    class Newctrl(base.Resource):
    """A volume is an extra block level storage to the OpenStack instances."""     def __repr__(self):
        return "<Newctrl>"     def delete(self):
        """Delete this sf iscsi storage."""         return self.manager.delete(self)
    
    
    '''class NewctrlManager(base.ManagerWithFind):''' class NewctrlManager(base.Manager):
    """Manage :class:`Newctrl` resources."""     resource_class = Newctrl
    
    def delete(self):
        print("just stub!")
    
    def newctrltest(self, string):
        body = {
            'string': string,
        }
        self._create('/newctrls', body, 'newctrltest')
    
    def newctrllist(self):
        self._list("/newctrls/detail", "volumes")

 

 

 

测试http请求是否发出:

# cinder --debug --os-volume-api-version=2 newctrlteststring='test string'

在cinder-api.log中可以看到:

curl -g -i -X POST http://ubuntu:8776/v2/949fd9b6d22a4bf8b65d9efd78b8d3c2/newctrls

说明http请求已经发出

 

接下来,完善cinder-api的控制器

 

2.   代码修改之cinder-api:增加API控制器

Cinder:

(1)      在cinder/api/v2中增加newctrls.py

 

 

import webob
    from webob import exc
    
    from cinder.i18n import _
    
    from oslo_log import log as logging
    from cinder.api.openstack import wsgi
    
    
LOG = logging.getLogger(__name__)
    
    
    class NewctrlController(wsgi.Controller):
    def __init__(self, ext_mgr):
        self.ext_mgr = ext_mgr
        super(NewctrlController, self).__init__()
        LOG.info("@ I AM IN NewctrlController __init__")
    
    def create(self, req, body):
        LOG.info("@ I AM IN NewctrlController create")
    
    def detail(self, req):
        """Returns a detailed list of volumes."""         LOG.info("@ I AM IN NewctrlController detail")
    
    def list(self, req):
        LOG.info("@ I AM IN NewctrlController list")
    
    
    def create_resource(ext_mgr):
    return wsgi.Resource(NewctrlController(ext_mgr))

 

 

 

 

(2)      增加到newctrl的路由,修改cinder/api/v2/router.py:

 

 

from cinder.api.v2importnewctrls

… …

self.resources['newctrls'] = newctrls.create_resource(ext_mgr)
mapper.resource("newctrl", "newctrls",
                controller=self.resources['newctrls'],
                collection={'detail':'GET'},
                member={'action':'POST'})

 

3.   测试遇到的问题及临时解决方法

http请求发过去

但看起来APIRouter没有route到NewctrlController

复现方法:

将newctrl.pyc删除,然后service cinder-api restart

 

Cinder-api.log:

- - [03/May/2016 18:26:52] "POST/v2/949fd9b6d22a4bf8b65d9efd78b8d3c2/newctrls HTTP/1.1" 404 2660.341194原因:

 

route.pyc没有重新生成,还是执行的修改之前的route.pyc,

如果rm route.pyc,重启cinder-api服务会报错

为什么没有重新生成?原因未知

临时解决方法:

因为route.py中引用了newctrls.py,将newctrls.py手动编译后,service cinder-api restart正常

所以,解决方法是:

手动编译newctrls:

python -m py_compile newctrls.py

这样生成了newctrls.pyc,然后service cinder-api restart服务时,也可以正常重启服务

但是python不是在执行的时候会自动编译的么?为什么这里newctrls.py需要手动编译才可一切正常,不手动编译,route.py就执行老的代码呢?根本原因需要探索。


猜想是安装的时候,会有一个地方执行编译操作,比如递归执行如下命令:

python -m compileall  ./

将所有文件编译为.pyc文件

 

也有可能是paste模块来编译的,搜索py_compile可以看到paste模块中有如下代码:

root@ubuntu:/usr/lib/python2.7/dist-packages/paste/script#grep "py_compile" ./ -r

Binary file ./grep.pyc matches

./grep.py:import py_compile

./grep.py:            py_compile.compile(filename)

先不进一步追究这个问题,以后遇到类似的情况,大家可以试一下

或者手动安装模块的时候,看下是不是有这么一步


4. 问题原因已明确及带给我的启示

新加的控制器文件newctrls.py,权限问题
权限是0600,router模块读取newctrls失败,导致报错:
ImportError: cannot import name newctrls
将新加的文件改为newctrls.py权限改为0644,运行正常

启示:对于新增文件的权限,以及属主,都是要考虑的问题




你可能感兴趣的:(在cinder中增加个控制器和API,通过cinderclient测试)