问题导读:
1、如何分析models.S3Image的定义?
前言
1、OpenStack建立实例完整过程源码详细分析(1)
2、OpenStack建立实例完整过程源码详细分析(2)
本文,继续接上一篇内容:
继续解析方法def show(self, context, image_id):
- def show(self, context, image_id):
- """
- # 调用之一传进来的参数:
- # context:上下文信息;
- # image_id=internal_id:实例镜像的ID值(从EC2 ID值变换了格式以后得到的);
- """
- # id_to_glance_id:根据数据库内置ID值(实例或者说是镜像的ID)获取数据库中相应的UUID值,赋值给image_uuid;
- image_uuid = ec2utils.id_to_glance_id(context, image_id)
-
- # 这里的service:service = service or glance.get_default_image_service();
- # 获取service或者是GlanceImageService的对象(glance.get_default_image_service()指向的);
- # 所以这里调用的还是/nova/image/glance.py中的show方法;
- image = self.service.show(context, image_uuid)
-
- # 转换镜像中的image_uuid到image_id;
- # 更新image当中的相关属性,返回更新后的image数据;
- return self._translate_uuid_to_id(context, image)
复制代码
1.2.3 self._translate_uuid_to_id(context, image)
- def _translate_uuid_to_id(self, context, image):
- """
- 调用glance_id_to_id方法转换image_copy['id']、image_copy['properties']['kernel_id']和image_copy['properties']['ramdisk_id'];
- 更新image当中的相关属性,返回更新后的image数据;
- """
-
- # 拷贝image对象给image_copy;
- image_copy = image.copy()
-
- try:
- image_uuid = image_copy['id']
- except KeyError:
- pass
- else:
- image_copy['id'] = ec2utils.glance_id_to_id(context, image_uuid)
-
- for prop in ['kernel_id', 'ramdisk_id']:
- try:
- image_uuid = image_copy['properties'][prop]
- except (KeyError, ValueError):
- pass
- else:
- image_id = ec2utils.glance_id_to_id(context, image_uuid)
- image_copy['properties'][prop] = image_id
-
- return image_copy
复制代码
总体来讲,这个方法实现的功能就是调用glance_id_to_id方法,转换image_copy['id']、image_copy['properties']['kernel_id']和image_copy['properties']['ramdisk_id'];
具体来看方法glance_id_to_id,这个方法实现了根据给定的glance_id值,查找到匹配的S3格式镜像数据信息,进一步获取镜像的id值返回:
- def glance_id_to_id(context, glance_id):
- """
- 根据给定的glance_id值,查找到匹配的S3格式镜像数据信息,进一步获取镜像的id值返回;
- """
- if glance_id is None:
- return
-
- # s3_image_get_by_uuid:通过给定的glance_id查找本地的S3格式的镜像;
- try:
- return db.s3_image_get_by_uuid(context, glance_id)['id']
- except exception.NotFound:
- return db.s3_image_create(context, glance_id)['id']
复制代码
方法s3_image_get_by_uuid实现了通过给定的image_uuid值到数据库中查找匹配的S3格式镜像数据信息,进入方法s3_image_get_by_uuid:
- def s3_image_get_by_uuid(context, image_uuid):
- """
- 通过给定的image_uuid查找S3格式的镜像数据信息;
- """
- result = model_query(context, models.S3Image, read_deleted="yes").\
- filter_by(uuid=image_uuid).\
- first()
-
- if not result:
- raise exception.ImageNotFound(image_id=image_uuid)
-
- return result
复制代码
我们再看models.S3Image的定义:
- class S3Image(BASE, NovaBase):
- """Compatibility layer for the S3 image service talking to Glance."""
- __tablename__ = 's3_images'
- id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
- uuid = Column(String(36), nullable=False)
复制代码
正如前面我们所说过的,这个类从NovaBase类继承,这也是model_query方法所要求的。看看这个类,我们可以理解为,它创建了一个数据库中的表s3_images,并且定义数据表的结构,有两个属性id和uuid;
所以我们就能够知道glance_id_to_id(context, glance_id)实现的是根据给定的glance_id值,查询数据库,找到匹配的表信息,获取它的S3Image.id值并返回,分别赋值给:image_copy['id']、image_copy['properties']['kernel_id']和image_copy['properties']['ramdisk_id'];
因为方法_translate_uuid_to_id中开始有一语句:
- image_copy = image.copy()
复制代码
拷贝image的对象给image_copy,注意这里所用的拷贝方法不是deepcopy,所以虽然实现拷贝但是实际上二者共享同一数据,所以image_copy改变的id值,同样image元数据中同样更新,所以直接返回了image_copy给方法def _get_image(self, context, ec2_id):
- def _get_image(self, context, ec2_id):
- """
- 获取ec2_id指定的镜像image数据;
- """
- try:
- ......
- image = self.image_service.show(context, internal_id)
复制代码
至此,源码分析(1)中所指出的方法def _get_image(self, context, ec2_id)中的语句:image = self.image_service.show(context, internal_id)全部解析完成;
至此,方法_get_image(self, context, ec2_id):也全部解析完成,这个方法实现的就是尝试链接glance客户端,根据ec2_id值获取匹配的镜像元数据分别赋值给kernel、ramdisk和image;
上一篇:
OpenStack建立实例完整过程源码详细分析(2)
|