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/

  <。)#)))≦

最新文章

  1. [LeetCode] Find All Numbers Disappeared in an Array 找出数组中所有消失的数字
  2. 2015年最好的PHP框架调查统计
  3. index()、e.target.value、on()与快捷处理的区别、
  4. LeetCode Graph Valid Tree
  5. [Matlab.Matrix] reshape
  6. 如何在Ubuntu/CentOS上安装Linux内核4.0
  7. python数据结构与算法——小猫钓鱼(使用队列)
  8. hibernate级联与反向
  9. SQL中如何检查死锁
  10. (六)6.7 Neurons Networks whitening
  11. wpf4 文字 模糊 不清晰 解决方法
  12. UVa 11992 (线段树 区间修改) Fast Matrix Operations
  13. CAS SiteMinder (单点登录)
  14. 2012在数据库技术会议上的讲话PPT打包
  15. linux 小技巧(磁盘空间搜索)
  16. sql server2008数据库复制实现数据同步常见问题
  17. Could not create pool connection. The DBMS driver exception was: null, message from server: &quot;Host &#39;192.168.XX.XX&#39; is blocked because of many connection errors; unblock with &#39;mysqladmin flush-hosts&#39;
  18. mybatis_ The content of element type association must match (constructor,id,result,ass ociation,collection,discriminator)
  19. Confluence 6 在初始化配置时候的问题
  20. Javascript高级编程学习笔记(10)—— 作用域、作用域链

热门文章

  1. 【干货】JavaScript DOM编程艺术学习笔记7-9
  2. mysql 5.7以上安装遇到的问题
  3. Tomcat Stack-8.0.35 (OpenLogic CentOS7.2)
  4. 美国L1签证面谈的时候一般VO会问到什么问题?
  5. spring xml 配置文件中标签的解析
  6. Oracle grant connect, resource to user语句中的权限
  7. Nginx学习记录(一)
  8. JDBC的连接mySql的基本知识
  9. WebSocket 详解
  10. 绘制矩形:描边矩形imagerectangle()、填充矩形imagefilledrectangle()