在强者的眼中,没有最好,只有更好。
此篇文章介绍关于在命令行输入相关命令之后,这个命令是如何调用并且执行的
代码结构
首先介绍一下代码目录的结构
1 | --ceilometerclient |
其中commonopenstack提供utils帮助类,tests是测试用例目录,v1v2分别对应ceilometer的v1和v2版本。client.py提供获取client的方法,包括keystone的client,提供获取endpoint和token的方法;还包括获取ceilometer的client的函数。shell.py是模块的入口,提供对命令行的解析和命令的调用。exc.py提供用到的异常类。
在每个版本目录下,代码的组织如下(v2为例):
1 | --v2 |
每个版本目录下也有一个client.py和一个shell.py,这里的shell.py里面提供了do_**的函数完成从上层shell.py传进来的命令并返回结果。其它的py文件按照名称以Manager类的形式分别对应ceilometer各个资源的操作实现。client.py引用所有的Manager,这样shell.py只需要依赖client一个就可以完成对各个资源的操作。
代码分析
代码入口在 /ceilometer/shell.py
1 | def main(args=None): |
当用户输入ceilometerXXX-后,程序通过main函数启动。首先是解析输入的命令参数。具体实现语句self.parse_args(argv)后面会详细介绍,这里实际也对输入的合法性做了验证,如果输入关键字不对或者格式不符合,会有相应的错误信息提示并退出。如果只输入ceilometer,则会直接调用do_help函数,效果等效于输入ceilometerhelp.如果解析正常,则parse_args返回版本信息api_version和解析结果args.
如果用户输入的是ceilometer help/bash_completion,则解析后的args中的func属性就对应为do_help/do_bash_completion函数(原理后面会解释)。
如果输入的是实际的操作命令(比如ceilometermeter-list),则先会做keystone鉴权认证,故执行命令前要设置好环境变量或者在命令中加上鉴权的参数;然后再根据版本号得到ceilometer的client,最后执行args.func(client,args)完成对应命令的实现(这里会调用do_meter_list函数)。
1 | class CeilometerShell(object): |
例如
当执行ceilometermeter-list -q xxx的时候,根据上面的分析,首先会创建好command为meter-list的subparser用来解析命令行,通过匹配最终将命令行字串解析成python对象,(比如meter-list解析成do_meter_list函数,-qxxx 解析为args.query).最终通过args.func(client,args)语句来执行do_meter_list。
1 |
|
cc即ceilometerclient.通过cc.meters.list列出满足args.query的meters值,最后通过utils.print_list打印出相应的字段。
参考:
https://blog.csdn.net/joey_5566/article/details/19413015?utm_source=blogxgwz4