Glance简介

  OpenStack镜像服务器是一套虚拟机镜像发现、注册、检索。

  glance架构图:

  

  Glance源码结构:

  

  glance/api:主要负责接收响应镜像管理命令的Restful请求,分析消息请求信息并分发其所带的命令(如新增,删除,更新等)。默认绑定端口是9292。

  glance/registry:主要负责接收响应镜像元数据命令的Restful请求。分析消息请求信息并分发其所带的命令(如获取元数据,更新元数据等)。默认绑定的端口是9191。

  glance/db:主要负责与数据库Mysql的交互

  glance/store:主要负责存储适配

  本次主要从简单的查询来简析glance源码,看一下glance代码是如何执行的。

  查询的API:/v1/images/detail,method:GET,有兴趣的朋友可以用火狐浏览器自带的RESTClient来进行REST服务的测试。

  好了,废话不多说,源码走起。

  源码分析

    图为glance/api/v1中的源码目录树。

   此次就从glance的查询来分析glance的源码,从horizon的传过来的HTTP请求首先来到glance/api/v1/router.py中,查找匹配的HTTP请求:

    代码如下:   

 mapper.connect("/images/detail",
controller=images_resource,
action='detail',
conditions={'method': ['GET']})

    可以看到,这与Glance的API文档是相符的,GET请求,然后是/v1/images/detail。

    而后,找到匹配的请求之后,就会进入glance/api/v1/images.py文件中,下面是有关的代码:  

 def detail(self, req):
"""
Returns detailed information for all available images :param req: The WSGI/Webob Request object
:retval The response body is a mapping of the following form:: {'images': [
{'id': <ID>,
'name': <NAME>,
'size': <SIZE>,
'disk_format': <DISK_FORMAT>,
'container_format': <CONTAINER_FORMAT>,
'checksum': <CHECKSUM>,
'min_disk': <MIN_DISK>,
'min_ram': <MIN_RAM>,
'store': <STORE>,
'status': <STATUS>,
'created_at': <TIMESTAMP>,
'updated_at': <TIMESTAMP>,
'deleted_at': <TIMESTAMP>|<NONE>,
'properties': {'distro': 'Ubuntu 10.04 LTS', ...}}, ...
]}
"""
self._enforce(req, 'get_images')
params = self._get_query_params(req)
try:
images = registry.get_images_detail(req.context, **params)
# Strip out the Location attribute. Temporary fix for
# LP Bug #755916. This information is still coming back
# from the registry, since the API server still needs access
# to it, however we do not return this potential security
# information to the API end user...
for image in images:
redact_loc(image, copy_dict=False)
self._enforce_read_protected_props(image, req)
except exception.Invalid as e:
raise HTTPBadRequest(explanation="%s" % e)
return dict(images=images)

   26行是根据获取查询条件,在此不深入谈,想了解的朋友可以留言,主要查询语句在try里面,也就是第28行: 

 images = registry.get_images_detail(req.context, **params)

  从这里,查询就跳入了glance/registry/client/v1/api.py文件中。

 

  图为glance/registry的目录树,glance/registry/client/v1/api.py中相关代码如下: 

 def get_images_detail(context, **kwargs):
c = get_registry_client(context)
return c.get_images_detailed(**kwargs)

  首先,会在glance/registry/client/v1/api.py文件进行registry端口的认证连接, 

 def get_registry_client(cxt):
global _CLIENT_CREDS, _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT
global _METADATA_ENCRYPTION_KEY
kwargs = _CLIENT_KWARGS.copy()
if CONF.use_user_token:
kwargs['auth_tok'] = cxt.auth_tok
if _CLIENT_CREDS:
kwargs['creds'] = _CLIENT_CREDS if CONF.send_identity_headers:
identity_headers = {
'X-User-Id': cxt.user,
'X-Tenant-Id': cxt.tenant,
'X-Roles': ','.join(cxt.roles),
'X-Identity-Status': 'Confirmed',
'X-Service-Catalog': jsonutils.dumps(cxt.service_catalog),
}
kwargs['identity_headers'] = identity_headers
return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT,
_METADATA_ENCRYPTION_KEY, **kwargs)

  然后第三行返回查询,进入glance/registry/client/v1/client.py中: 

 def get_images_detailed(self, **kwargs):
"""
Returns a list of detailed image data mappings from Registry :param filters: dict of keys & expected values to filter results
:param marker: image id after which to start page
:param limit: max number of images to return
:param sort_key: results will be ordered by this image attribute
:param sort_dir: direction in which to to order results (asc, desc)
"""
params = self._extract_params(kwargs, images.SUPPORTED_PARAMS)
res = self.do_request("GET", "/images/detail", params=params)
image_list = jsonutils.loads(res.read())['images']
for image in image_list:
image = self.decrypt_metadata(image)
return image_list

  在12行再次发出请求,然后在glance/registry/api/v1/__init__.py中查找匹配的请求:  

 mapper.connect("/images/detail",
controller=images_resource,
action="detail",
conditions={'method': ['GET']})

  在glance/registry/api/v1/images.py中找到相应的方法进行查询:

 def detail(self, req):
"""Return a filtered list of public, non-deleted images in detail :param req: the Request object coming from the wsgi layer
:retval a mapping of the following form:: dict(images=[image_list]) Where image_list is a sequence of mappings containing
all image model fields.
"""
params = self._get_query_params(req) images = self._get_images(req.context, **params)
image_dicts = [make_image_dict(i) for i in images]
LOG.info(_("Returning detailed image list"))
return dict(images=image_dicts)

  第14行又调用glance/registry/api/v1/images.py的_get_images(req.context, **params)方法:

 def _get_images(self, context, filters, **params):
"""Get images, wrapping in exception if necessary."""
# NOTE(markwash): for backwards compatibility, is_public=True for
# admins actually means "treat me as if I'm not an admin and show me
# all my images"
if context.is_admin and params.get('is_public') is True:
params['admin_as_user'] = True
del params['is_public']
try:
return self.db_api.image_get_all(context, filters=filters,
**params)
except exception.NotFound:
LOG.info(_("Invalid marker. Image %(id)s could not be "
"found.") % {'id': params.get('marker')})
msg = _("Invalid marker. Image could not be found.")
raise exc.HTTPBadRequest(explanation=msg)
except exception.Forbidden:
LOG.info(_("Access denied to image %(id)s but returning "
"'not found'") % {'id': params.get('marker')})
msg = _("Invalid marker. Image could not be found.")
raise exc.HTTPBadRequest(explanation=msg)
except Exception:
LOG.exception(_("Unable to get images"))
raise

  在第10行中,进入glance/db/sqlalchemy/api.py中:

  图为glance/db的目录树。下面是调用的glance/db/sqlalchemy/api.py中的image_get_all方法,

  

 def image_get_all(context, filters=None, marker=None, limit=None,
sort_key='created_at', sort_dir='desc',
member_status='accepted', is_public=None,
admin_as_user=False):
"""
Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties'
key is present, it is treated as a dict of key/value
filters on the image properties attribute
:param marker: image id after which to start page
:param limit: maximum number of images to return
:param sort_key: image attribute by which results should be sorted
:param sort_dir: direction in which results should be sorted (asc, desc)
:param member_status: only return shared images that have this membership
status
:param is_public: If true, return only public images. If false, return
only private and shared images.
:param admin_as_user: For backwards compatibility. If true, then return to
an admin the equivalent set of images which it would see
if it were a regular user
"""
filters = filters or {} visibility = filters.pop('visibility', None)
showing_deleted = 'changes-since' in filters or filters.get('deleted',
False) img_conditions, prop_conditions, tag_conditions = \
_make_conditions_from_filters(filters, is_public) query = _select_images_query(context,
img_conditions,
admin_as_user,
member_status,
visibility) if visibility is not None:
if visibility == 'public':
query = query.filter(models.Image.is_public == True)
elif visibility == 'private':
query = query.filter(models.Image.is_public == False) if prop_conditions:
for prop_condition in prop_conditions:
query = query.join(models.ImageProperty, aliased=True)\
.filter(sa_sql.and_(*prop_condition)) if tag_conditions:
for tag_condition in tag_conditions:
query = query.join(models.ImageTag, aliased=True)\
.filter(sa_sql.and_(*tag_condition)) marker_image = None
if marker is not None:
marker_image = _image_get(context,
marker,
force_show_deleted=showing_deleted) sort_keys = ['created_at', 'id']
sort_keys.insert(0, sort_key) if sort_key not in sort_keys else sort_keys query = _paginate_query(query, models.Image, limit,
sort_keys,
marker=marker_image,
sort_dir=sort_dir) query = query.options(sa_orm.joinedload(models.Image.properties))\
.options(sa_orm.joinedload(models.Image.locations)) return [_normalize_locations(image.to_dict()) for image in query.all()]

  此方法最后将查询结果返回字典,至此,glance查询方法就此结束。

  如果有不对的地方,欢迎各位大神指出。

PS:本博客欢迎转发,但请注明博客地址及作者~

  博客地址:http://www.cnblogs.com/voidy/

  <。)#)))≦

OpenStack之Glance源码简析的更多相关文章

  1. SpringMVC学习(一)——概念、流程图、源码简析

    学习资料:开涛的<跟我学SpringMVC.pdf> 众所周知,springMVC是比较常用的web框架,通常整合spring使用.这里抛开spring,单纯的对springMVC做一下总 ...

  2. Flink源码阅读(一)——Flink on Yarn的Per-job模式源码简析

    一.前言 个人感觉学习Flink其实最不应该错过的博文是Flink社区的博文系列,里面的文章是不会让人失望的.强烈安利:https://ververica.cn/developers-resource ...

  3. django-jwt token校验源码简析

    一. jwt token校验源码简析 1.1 前言 之前使用jwt签发了token,里面的头部包含了加密的方式.是否有签名等,而载荷中包含用户名.用户主键.过期时间等信息,最后的签名还使用了摘要算法进 ...

  4. 0002 - Spring MVC 拦截器源码简析:拦截器加载与执行

    1.概述 Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理.例如通过拦截器可以进行权限验证.记录请求信息的日 ...

  5. AFNetworking源码简析

    AFNetworking基本是苹果开发中网络请求库的标配,它是一个轻量级的网络库,专门针对iOS和OS X的网络应用设计,具有模块化的架构和丰富的APIs接口,功能强大并且使用简单,深受苹果应用开发人 ...

  6. ElementUI 源码简析——源码结构篇

    ElementUI 作为当前运用的最广的 Vue PC 端组件库,很多 Vue 组件库的架构都是参照 ElementUI 做的.作为一个有梦想的前端(咸鱼),当然需要好好学习一番这套比较成熟的架构. ...

  7. DRF之APIView源码简析

    一. 安装djangorestframework 安装的方式有以下三种,注意,模块就叫djangorestframework. 方式一:pip3 install djangorestframework ...

  8. spring ioc源码简析

    ClassPathXmlApplicationContext 首先我们先从平时启动spring常用的ClassPathXmlApplicationContext开始解析 ApplicationCont ...

  9. 并发系列(二)——FutureTask类源码简析

    背景 本文基于JDK 11,主要介绍FutureTask类中的run().get()和cancel() 方法,没有过多解析相应interface中的注释,但阅读源码时建议先阅读注释,明白方法的主要的功 ...

随机推荐

  1. mathtype 章节号 Equation Chapter 1 Section 1 的去除

    mathtype 章节号 Equation Chapter 1 Section 1 的去除 转:http://hi.baidu.com/17ximm/blog/item/2882413e92fc96c ...

  2. HTTPS的加密流程(通俗易懂,不可错过)

    为什么要有HTTPS 都说进技术的产生就是为了解决旧技术的一些弊端. HTTP具有相当优秀的一面,但是凡事有利也有弊,在HTTP进行高速通信的过程中可能产生以下几个问题: HTTP采用明文传输.明文传 ...

  3. 关于dependencies和devDependencies的理解

    npm install 会下载dependencies和devDependencies中的模块,当使用npm install --production或者注明NODE_ENV变量值为productio ...

  4. Vultr VPS建站攻略 – 一键安装LNMP无面板高性能WEB环境

    在"Vultr VPS建站攻略 - 一键安装宝塔面板架设LNMP/LAMP Web环境"文章中,VULTR中文网分享到我们常用的可视化面板宝塔面板安装在VULTR VPS主机中建站 ...

  5. UML复习1-2章

    第一章 1.请对SDLC的六个阶段排序 1> 可行性分析 2> 设计 3> 测试 4> 维护 5> 需求分析与说明 6> 编码 A. 1 5 2 6 3 4 B. ...

  6. shell 快速浏览

    总结自: https://github.com/qinjx/30min_guides/blob/master/shell.md: http://blog.itpub.net/14293828/view ...

  7. TFS看板的设计

    列 产品开发的整个流程如下图,将流程配置到看板的列: 需求池-->就绪-->开发-->测试-->待验收 -->待发布 -->已关闭 一般将Bug和需求放在一块看版上 ...

  8. UVA 12166 Equilibrium Mobile(贪心,反演)

    直接贪心.先想想最后平衡的时候,如果知道了总重量,那么每一个结点的重量其实也就确定了. 每个结点在左在右其实都不影响,只和层数有关.现在反过来,如果不修改某个结点,那么就可以计算出总质量,取总质量出现 ...

  9. Airflow 调度基础

    1. Airflow Airflow是一个调度.监控工作流的平台.用于将一个工作流制定为一组任务的有向无环图(DAG),并指派到一组计算节点上,根据相互之间的依赖关系,有序执行. 2. 安装 pip安 ...

  10. subline 安装 package control

    subline text2 输入 import urllib2,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa154 ...