OpenStack建立实例完整过程源码详细分析(4)

感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!
如果转载,请保留作者信息。
博客地址:http://blog.csdn.net/gaoxingnengjisuan
邮箱地址:dong.liu@siat.ac.cn


    再回到源码详细分析(1)中最开始的方法run_instances:

def run_instances(self, context, **kwargs):  
            """
            准备实例,并且发送实例的信息和要运行实例的请求消息到远程调度器scheduler; 
            实现实例的简历和运行,由调度器完成; 
            """
              
            # 设置最小建立实例的数目;  
            min_count = int(kwargs.get('min_count', 1))  
              
            # 获取kwargs['kernel_id']指定的镜像image数据返回给kernel;  
            # 获取更新的kwargs['kernel_id'];  
            if kwargs.get('kernel_id'):   
                kernel = self._get_image(context, kwargs['kernel_id'])  
                # 根据kernel['id']查询数据库中匹配的S3镜像数据,获取它的uuid属性,并返回;  
                # 返回匹配的db.models.S3Image.uuid给kwargs['kernel_id'];  
                kwargs['kernel_id'] = ec2utils.id_to_glance_id(context, kernel['id'])  
                  
            # 获取kwargs['ramdisk_id']指定的镜像image数据返回给ramdisk;  
            # 获取更新的kwargs['ramdisk_id'];  
            if kwargs.get('ramdisk_id'):  
                ramdisk = self._get_image(context, kwargs['ramdisk_id'])              
                # 根据ramdisk['id']查询数据库中匹配的S3镜像数据,获取它的uuid属性,并返回;  
                # 返回匹配的db.models.S3Image.uuid给kwargs['ramdisk_id'];  
                kwargs['ramdisk_id'] = ec2utils.id_to_glance_id(context, ramdisk['id'])  
                  
            # 循环获取每一个块设备映射;  
            # 解析块设备映射bdm;  
            for bdm in kwargs.get('block_device_mapping', []):  
                _parse_block_device_mapping(bdm)  
      
            # 获取kwargs['image_id']指定的镜像image数据;  
            image = self._get_image(context, kwargs['image_id'])  
            # 根据image['id']查询数据库中匹配的S3镜像数据,获取它的uuid属性,并返回;  
            # 返回匹配的db.models.S3Image.uuid给image_uuid;  
            image_uuid = ec2utils.id_to_glance_id(context, image['id'])  
      
            # 获取镜像image的状态;  
            if image:  
                image_state = self._get_image_state(image)  
            else:  
                raise exception.ImageNotFoundEC2(image_id=kwargs['image_id'])  
      
            if image_state != 'available':  
                raise exception.EC2APIError(_('Image must be available'))  
       
            (instances, resv_id) = self.compute_api.create(context,   
                instance_type=instance_types.get_instance_type_by_name(kwargs.get('instance_type', None)),  
                image_href=image_uuid,  
                max_count=int(kwargs.get('max_count', min_count)),  
                min_count=min_count,  
                kernel_id=kwargs.get('kernel_id'),  
                ramdisk_id=kwargs.get('ramdisk_id'),  
                key_name=kwargs.get('key_name'),  
                user_data=kwargs.get('user_data'),  
                security_group=kwargs.get('security_group'),  
                availability_zone=kwargs.get('placement', {}).get('availability_zone'),  
                block_device_mapping=kwargs.get('block_device_mapping', {}))  
            return self._format_run_instances(context, resv_id)
    我们来解析第二个比较重要的语句_parse_block_device_mapping(bdm):

    我们先来看看kwargs中'block_device_mapping'所表示的数据形式:

    [
           ({'device_name': '/dev/fake0',
              'ebs': {'snapshot_id': 'snap-12345678',
                      'volume_size': 1}},
            {'device_name': '/dev/fake0',
             'snapshot_id': '00000000-1111-2222-3333-444444444444',
             'volume_size': 1,
             'delete_on_termination': True}),

            ({'device_name': '/dev/fake1',
              'ebs': {'snapshot_id': 'snap-23456789',
                      'delete_on_termination': False}},
             {'device_name': '/dev/fake1',
              'snapshot_id': '11111111-2222-3333-4444-555555555555',
              'delete_on_termination': False}),

            ({'device_name': '/dev/fake2',
              'ebs': {'snapshot_id': 'vol-87654321',
                      'volume_size': 2}},
            {'device_name': '/dev/fake2',
             'volume_id': '22222222-3333-4444-5555-666666666666',
             'volume_size': 2,
             'delete_on_termination': True}),

            ({'device_name': '/dev/fake3',
              'ebs': {'snapshot_id': 'vol-98765432',
                      'delete_on_termination': False}},
             {'device_name': '/dev/fake3',
              'volume_id': '77777777-8888-9999-0000-aaaaaaaaaaaa',
              'delete_on_termination': False}),

            ({'device_name': '/dev/fake4',
              'ebs': {'no_device': True}},
             {'device_name': '/dev/fake4',
              'no_device': True}),

            ({'device_name': '/dev/fake5',
             'virtual_name': 'ephemeral0'},
            {'device_name': '/dev/fake5',
             'virtual_name': 'ephemeral0'}),

            ({'device_name': '/dev/fake6',
             'virtual_name': 'swap'},
            {'device_name': '/dev/fake6',
             'virtual_name': 'swap'}),
    ]

2.方法_parse_block_device_mapping的源码分析: 

def _parse_block_device_mapping(bdm):
    """
    解析块设备映射bdm;
    """
    ebs = bdm.pop('ebs', None)
    if ebs:
        ec2_id = ebs.pop('snapshot_id', None)
        if ec2_id:
            # 判断如果是快照;
            # 则根据获取的ec2_id值,从匹配的数据库信息中获取uuid值赋值给bdm['snapshot_id'],更新bdm中的相应数据;
            if ec2_id.startswith('snap-'):
                bdm['snapshot_id'] = ec2utils.ec2_snap_id_to_uuid(ec2_id)
            # 判断如果是volume;
            # 则根据获取的ec2_id值,从匹配的数据库信息中获取uuid值赋值给bdm['snapshot_id'],更新bdm中的相应数据;
            elif ec2_id.startswith('vol-'):
                bdm['volume_id'] = ec2utils.ec2_vol_id_to_uuid(ec2_id)
                           
            ebs.setdefault('delete_on_termination', True)
        
        # 更新bdm;
        bdm.update(ebs)
    
    # 返回更新后的bdm;
    return bdm
     这个方法主要完成的就是读取数据库,获取相应数据更新上述实例数据中的'snapshot_id'和'volume_id'值;

     例如,针对bdm信息:

    (          {'device_name': '/dev/fake0',
                 'ebs': {'snapshot_id': 'snap-12345678',
                            'volume_size': 1}},
               {'device_name': '/dev/fake0',
                 'snapshot_id': '00000000-1111-2222-3333-444444444444',
                 'volume_size': 1,
                 'delete_on_termination': True})

    ec2_id的值即为'snap-12345678';

    再看方法ec2utils.ec2_snap_id_to_uuid(ec2_id):

def ec2_snap_id_to_uuid(ec2_id):
    """
    为给定的ec2-id获取相应快照的UUID值;
    """
    
    # 获取admin的上下文信息;
    ctxt = context.get_admin_context()

    # 转换一个EC2的ID为一个实例的ID(INT格式);(主要是格式变换的问题)
    int_id = ec2_id_to_id(ec2_id)
    
    # 根据给定的int_id获取相应快照的UUID值;
    return get_snapshot_uuid_from_int_id(ctxt, int_id)
     语句int_id = ec2_id_to_id(ec2_id)实际上就是获取整型数据12345678赋值给int_id;

     进一步调用了方法get_snapshot_uuid_by_ec2_id:

def get_snapshot_uuid_by_ec2_id(context, ec2_id, session=None):
    """根据给定的ec2_id获取相应快照的UUID值;"""
    result = _ec2_snapshot_get_query(context, session=session).\
                    filter_by(id=ec2_id).\
                    first()

    if not result:
        raise exception.SnapshotNotFound(snapshot_id=ec2_id)

    return result['uuid']
     可见根据传入的参数 ec2_id=12345678,查询匹配的快照数据库信息,并且获取数据库内置的uuid值最终返回给方法_parse_block_device_mapping中的bdm['snapshot_id'];

     获取bdm['volume_id']值的方法流程是一样的,只不过一个是针对快照类型的bdm['snapshot_id'],一个是针对卷类型的bdm['volume_id'];

     设置'delete_on_termination'的值为true;

     更新相关的bdm数据信息;

     后面将会开始解析重要的creat方法;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值