Example #1
0
def instance_performance_data_to_other_platform():
    '''获取web服务器的性能数据'''
    msg = ''
    command = "supervisorctl status | awk -F ' ' '{print $2}'"
    supervisorctl_data = os.popen(command).read()
    supervisorctl_list = supervisorctl_data.split('\n')[:-1]
    for i in supervisorctl_list:
        if i.strip() != "RUNNING":
            msg += 'web服务器性能数据存在非running状态; '
    table_vishi = ip_lock_service.IpLockService().get_ip_lock_info(
        "performance_data")
    if table_vishi:
        update_data = {"istraceing": "0"}
        where_data = {"table_name": "performance_data"}
        ip_lock_service.IpLockService().update_ip_lock_info(
            update_data, where_data)

    else:
        insert_data = {"table_name": "performance_data", "istraceing": "0"}
        ip_lock_service.IpLockService().add_ip_lock_db(insert_data)
    ret_ip_lock = ip_lock_service.IpLockService().get_ip_lock_info(
        "performance_data")
    if ret_ip_lock["istraceing"] != "0":
        msg += 'web服务器性能数据设置检测初始化数据失败; '
    data = {
        "routing_key": "INSTANCE.PERFORMANCE",
        "send_time": get_datetime_str(),
        "data": {
            "table_name": "performance_data"
        }
    }
    send_async_msg(KAFKA_TOPIC_NAME, data)
    nums = 0
    status = False
    while nums < 10:
        table_vishi = ip_lock_service.IpLockService().get_ip_lock_info(
            "performance_data")
        if str(table_vishi["istraceing"]) == '1':
            status = True
            break
        else:
            nums += 1
            time.sleep(1)
    if not status:
        msg += 'kafka消费任务异常,超时10秒; '
    if msg:
        return json_helper.format_api_resp_msg_to_vishnu_resource(
            job_status=VsJobStatus.FAILED, detail=msg)
    return json_helper.format_api_resp_msg_to_vishnu_resource(
        job_status=VsJobStatus.SUCCEED, detail='web服务器正常,kafka消费正常')
def instance_hot_migrate(instance_id, host_id):
    '''
        虚拟机迁移
    :param instance_id:
    :param host_id:
    :return:
    '''
    speed_limit = request.values.get('speed_limit')
    if not instance_id or not host_id or not speed_limit or int(
            speed_limit) < 0:
        logging.info('the params is invalid when migrate instance')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg="参数错误")

    host_data_s = ins_s.get_host_of_instance(instance_id)
    if not host_data_s:
        logging.error(
            'instance %s of host is not exist in db when migrate instance',
            str(instance_id))
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    host_data_d = host_s.HostService().get_host_info(host_id)
    if not host_data_d:
        logging.error(
            'target host %s is not exist in db when migrate instance',
            str(instance_id))
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    if host_data_d['typestatus'] == HostTypeStatus.LOCK or host_data_d[
            'typestatus'] == HostTypeStatus.MAINTAIN:
        logging.error(
            'target host %s is in invalid status %s when migrate instance',
            host_id, host_data_d['typestatus'])
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='不能迁移到锁定或维护的主机上')

    ins_flavor_data = ins_s.get_flavor_of_instance(instance_id)
    if not ins_flavor_data:
        logging.error('hot migrate can not get instance %s flavor info' %
                      str(instance_id))
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='无法获取被迁移虚拟机的基础配置信息')

    ins_group = ins_g_s.InstanceGroupService().get_instance_group_info(
        instance_id)
    if not ins_group:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="无法获取虚拟机所在应用组信息")

    data_disk_status, data_disk_size = ins_s.get_data_disk_size_of_instance(
        instance_id)
    if not data_disk_status:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="无法获取被迁移虚拟机磁盘配置信息")
    instance_disk_size = int(
        ins_flavor_data['root_disk_gb']) + int(data_disk_size)

    # 获取物理机所在资源池可用物理机数量
    all_hosts_nums, all_hosts_data = host_s.HostService(
    ).get_available_hosts_of_hostpool(host_data_d["hostpool_id"])
    if all_hosts_nums < 1:
        return False, '集群物理机资源不足,无法满足虚拟机迁移'

    host_data_d_before_match = []
    host_data_d_before_match.append(host_data_d)

    # 过滤host
    # 这里不核对host的cpu型号
    hosts_after_filter = host_s_s.migrate_filter_hosts(
        host_data_d_before_match, int(all_hosts_nums))
    if len(hosts_after_filter) == 0:
        logging.info('no available host when get migrate host')
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="集群内其他物理机cpu、内存使用率超过阀值,暂时不能迁移")

    # VM分配给HOST看是否满足迁移
    vm = {
        "vcpu": ins_flavor_data['vcpu'],
        "mem_MB": ins_flavor_data['memory_mb'],
        "disk_GB": instance_disk_size,
    }
    host_after_match = host_s_s.migrate_match_hosts(hosts_after_filter,
                                                    vm,
                                                    ins_group['group_id'],
                                                    least_host_num=1,
                                                    max_disk=2000)
    if len(host_after_match) == 0:
        logging.info('no available host when get migrate host')
        return json_helper.format_api_resp(
            code=ErrorCode.SYS_ERR, msg="集群内其他物理机cpu、内存资源不足或者应用互斥,暂时不能迁移")

    # 不能本身
    if host_data_s['id'] == host_id:
        logging.error('no allow migrate to the same host %s', host_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="不能迁移到原主机上")

    ins_data_s = ins_s.InstanceService().get_instance_info(instance_id)
    if not ins_data_s:
        logging.error('instance %s is not exist in db when migrate instance')
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 排除非法状态,vm只能在开机状态下才能热迁移
    if ins_data_s['status'] != VMStatus.STARTUP or ins_data_s[
            'typestatus'] != VMTypeStatus.NORMAL:
        logging.error(
            'instance status %s, typestatus %s is invalid when migrate instance',
            ins_data_s['status'], ins_data_s['typestatus'])
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='只能在关机状态下执行热迁移')

    # 检测目标主机是否有迁入VM
    if not _check_has_migrate(host_id):
        logging.error(
            'dest host %s has other migrating instance when migrate instance',
            host_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='目标主机现有正在迁入的虚机,不能迁移到该主机')

    # 将VM状态改为热迁移中
    update_data = {
        'status': VMStatus.MIGRATE,  # 热迁移中
        'updated_at': get_datetime_str()
    }
    where_data = {'id': instance_id}
    ret = ins_s.InstanceService().update_instance_info(update_data, where_data)
    if ret != 1:
        logging.error(
            'update instance status error when cold migrate, update_data:%s, where_data:%s',
            update_data, where_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    ins_data = ins_s.InstanceService().get_instance_info(instance_id)

    # 新增一个instance_dsthost记录,dsthost为目标host的ip
    # 迁移过程中失败则删除这条新增的Instance_dsthost记录,迁移成功之后则删除Instance_srchost记录
    # 迁移过程中前端vm页面不会显示这条新增的记录
    instance_host_data = {
        'instance_id': instance_id,
        'instance_name': ins_data['name'],
        'host_id': host_id,
        'host_name': host_data_d['name'],
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret_h = ins_h_s.InstanceHostService().add_instance_host_info(
        instance_host_data)
    if ret_h.get('row_num') <= 0:
        logging.error(
            'add instance host info error when hot migrate, %instance_id,%host_id'
        )
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 在instance_migrate表中增加一条数据
    insert_data = {
        'instance_id': instance_id,
        'src_host_id': host_data_s['id'],
        'dst_host_id': host_id,
        'migrate_status': MigrateStatus.DOING,
        'created_at': get_datetime_str()
    }
    ret_m = ins_m_s.InstanceMigrateService().add_instance_migrate_info(
        insert_data)
    if ret_m.get('row_num') <= 0:
        logging.error(
            'add instance migrate info error when cold migrate, insert_data:%s',
            insert_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 发送异步消息到队列
    data = {
        "routing_key": "INSTANCE.HOTMIGRATE",
        "send_time": get_datetime_str(),
        "data": {
            "request_id": ins_s.generate_req_id(),
            "user_id": get_user()['user_id'],
            "migrate_tab_id": ret_m.get('last_id'),
            "task_id": ins_s.generate_task_id(),
            "speed_limit": speed_limit,
            "ins_data_s": {
                "id": ins_data_s['id'],
                "uuid": ins_data_s['uuid'],
                "name": ins_data_s['name']
            },
            "host_data_d": {
                "id": host_data_d['id'],
                "name": host_data_d['name'],
                "ipaddress": host_data_d['ipaddress']
            },
            "host_data_s": {
                "id": host_data_s['id'],
                "name": host_data_s['name'],
                "ipaddress": host_data_s['ipaddress'],
                "sn": host_data_s['sn']
            }
        }
    }

    # todo:这里有可能发送不成功
    ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data)

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Example #3
0
def _create_instance_info(task_id, instance_name, app_info, owner, password,
                          flavor_id, group_id, vm_host, flavor_info,
                          image_data, ip_data, vm_disk_gb, mount_point,
                          instance_system, net_area_id, segment_data, vm_env,
                          user_id):
    uuid = randomUUID()
    request_id = ins_s.generate_req_id()
    # 往instance表添加记录
    logging.info(
        '创建VM 步骤10-1:插入instance表 task %s : insert instance table start when create instance',
        task_id)
    instance_data = {
        'uuid': uuid,
        'name': instance_name,
        'displayname': instance_name,
        'description': '',
        'status': VMStatus.CREATING,
        'typestatus': VMTypeStatus.NORMAL,
        'create_source': VMCreateSource.CLOUD_SOURCE,
        'isdeleted': '0',
        'app_info': app_info,
        'owner': owner,
        'created_at': get_datetime_str(),
        'password': encrypt_helper.encrypt(str(password)),  # 密码加密
        'request_id': request_id,
        'task_id': task_id
    }
    ret = ins_s.InstanceService().add_instance_info(instance_data)
    if ret.get('row_num') <= 0:
        logging.error(
            'task %s : add instance info error when create instance, insert_data: %s',
            task_id, instance_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-1:插入instance表成功 '
        'task %s : insert instance table successful when create instance',
        task_id)

    instance_id = ret.get('last_id')

    # 往instance_flavor表添加记录
    logging.info(
        '创建VM 步骤10-2:插入instance_flavor表 '
        'task %s : insert instance_flavor table start when create instance',
        task_id)
    instance_flavor_data = {
        'instance_id': instance_id,
        'flavor_id': flavor_id,
        'created_at': get_datetime_str()
    }
    ret1 = ins_f_s.InstanceFlavorService().add_instance_flavor_info(
        instance_flavor_data)
    if ret1.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_flavor info error when create instance, insert_data: %s',
            task_id, instance_flavor_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-2:插入instance_flavor表成功 '
        'task %s : insert instance_flavor table successful when create instance',
        task_id)

    # 往instance_group表添加记录
    logging.info(
        '创建VM 步骤10-3:插入instance_group表 task %s : insert instance_group table start when create instance',
        task_id)
    instance_group_data = {
        'instance_id': instance_id,
        'group_id': group_id,
        'created_at': get_datetime_str()
    }
    ret2 = ins_g_s.InstanceGroupService().add_instance_group_info(
        instance_group_data)
    if ret2.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_group info error when create instance, insert_data: %s',
            task_id, instance_group_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-3:插入instance_group表成功 task %s : insert instance_group table successful when create instance',
        task_id)

    # 往instance_host表添加记录
    logging.info(
        '创建VM 步骤10-4:插入instance_host表 task %s : insert instance_host table start when create instance',
        task_id)
    instance_host_data = {
        'instance_id': instance_id,
        'instance_name': instance_name,
        'host_id': vm_host['host_id'],
        'host_name': vm_host['name'],
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret3 = ins_h_s.InstanceHostService().add_instance_host_info(
        instance_host_data)
    if ret3.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_host info error when create instance, insert_data: %s',
            task_id, instance_host_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-4:插入instance_host表成功 '
        'task %s : insert instance_host table successful when create instance',
        task_id)

    # host预分配资源
    logging.info(
        '创建VM 步骤10-5:host预分配资源 task %s : pre allocate host resource start when create instance',
        task_id)
    ret4 = host_s.pre_allocate_host_resource(vm_host['host_id'],
                                             flavor_info['vcpu'],
                                             flavor_info['memory_mb'],
                                             flavor_info['root_disk_gb'])
    if ret4 != 1:
        logging.error(
            'task %s : pre allocate host resource to db error when create instance',
            task_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-5:host预分配资源成功 '
        'task %s : pre allocate host resource successful when create instance',
        task_id)

    # 往instance_image表添加记录
    logging.info(
        '创建VM 步骤10-6:插入instance_image表 task %s : insert instance_image table start when create instance',
        task_id)
    for _image in image_data:
        instance_image_data = {
            'instance_id': instance_id,
            'image_id': _image['id'],
            'created_at': get_datetime_str()
        }
        ret5 = ins_img_s.InstanceImageService().add_instance_image_info(
            instance_image_data)
        if ret5.get('row_num') <= 0:
            logging.error(
                'task %s : add instance_image info error when create instance, insert_data: %s',
                task_id, instance_image_data)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-6:插入instance_image表成功 '
        'task %s : insert instance_image table successful when create instance',
        task_id)

    # 往instance_ip表添加记录
    logging.info(
        '创建VM 步骤10-7:插入instance_ip表 '
        'task %s : insert instance_ip table start when create instance',
        task_id)
    mac = randomMAC()
    data_ip_address = ip_data['ip_address']
    instance_ip_data = {
        'instance_id': instance_id,
        'ip_id': ip_data['id'],
        'mac': mac,
        'type': InstanceNicType.MAIN_NETWORK_NIC,
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret6 = ins_ip_s.InstanceIPService().add_instance_ip_info(instance_ip_data)
    if ret6.get('row_num') <= 0:
        logging.error(
            'task %s : add instance_ip info error when create instance, insert_data: %s',
            task_id, instance_ip_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-7:插入instance_ip表成功 '
        'task %s : insert instance_ip table successful when create instance',
        task_id)

    # 标识该IP为已使用
    logging.info(
        '创建VM 步骤10-8:设置IP为已使用 task %s : set ip used start when create instance',
        task_id)
    update_data = {'status': IPStatus.USED}
    where_data = {'id': ip_data['id']}
    ret7 = ip_service.IPService().update_ip_info(update_data, where_data)
    if ret7 <= 0:
        logging.info(
            'task %s : update ip info error when create instance, update_data: %s, where_data: %s',
            task_id, update_data, where_data)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    logging.info(
        '创建VM 步骤10-8:设置IP为已使用成功 task %s : set ip used successful when create instance',
        task_id)

    # 拼装消息需要的镜像信息
    logging.info(
        '创建VM 步骤10-9:拼装所需的镜像信息 '
        'task %s : piece together need image info start when create instance',
        task_id)
    image_list = []
    # 数据盘数量
    data_image_num = 0
    for _image in image_data:
        _image_type = _image['type']
        _info = {
            "disk_format": _image['format'],
            "url": _image['url'],
            # "md5sum": _image['md5'],
            "image_size_gb": _image['size_gb']  # 镜像预分配大小
        }
        # 系统盘
        if _image_type == ImageType.SYSTEMDISK:
            _disk_name = instance_name + '.img'
            _info['image_dir_path'] = '/app/image/' + uuid + '/' + _disk_name
            _info['disk_name'] = _disk_name
            _info['disk_size_gb'] = None
            _info['dev_name'] = 'vda'

            # 如果只有一块盘且为系统盘,则预先分配一块数据盘的数据存入instance_disk表
            if len(image_data) == 1:
                logging.info(
                    'task %s : pre insert instance_disk table that has only one system disk start when create '
                    'instance', task_id)
                instance_disk_data = {
                    'instance_id': instance_id,
                    'size_gb': vm_disk_gb,
                    'mount_point': mount_point,
                    'dev_name': 'vdb',
                    'isdeleted': '0',
                    'created_at': get_datetime_str()
                }
                ret9 = ins_d_s.InstanceDiskService().add_instance_disk_info(
                    instance_disk_data)
                if ret9.get('row_num') <= 0:
                    logging.info(
                        'task %s : pre add instance_disk info that has only one system disk error when create '
                        'instance, insert_data: %s', task_id,
                        instance_disk_data)
                    return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
                logging.info(
                    'task %s : pre insert instance_disk table that has only one system disk successful when '
                    'create instance', task_id)
        else:
            # 数据盘
            _disk_name = instance_name + '.disk' + str(data_image_num + 1)
            _disk_dev_name = _get_vd_map(data_image_num)
            _info['image_dir_path'] = '/app/image/' + uuid + '/' + _disk_name
            _info['disk_name'] = _disk_name
            _info['disk_size_gb'] = vm_disk_gb
            _info['dev_name'] = _disk_dev_name
            data_image_num += 1

            # 往instance_disk表添加记录
            logging.info(
                'task %s : insert instance_disk table start when create instance',
                task_id)
            instance_disk_data = {
                'instance_id': instance_id,
                'size_gb': vm_disk_gb,
                'mount_point': mount_point,
                'dev_name': _disk_dev_name,
                'isdeleted': '0',
                'created_at': get_datetime_str()
            }
            ret8 = ins_d_s.InstanceDiskService().add_instance_disk_info(
                instance_disk_data)
            if ret8.get('row_num') <= 0:
                logging.info(
                    'task %s : add instance_disk info error when create instance, insert_data: %s',
                    task_id, instance_disk_data)
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
            logging.info(
                'task %s : insert instance_disk table successful when create instance',
                task_id)

        image_list.append(_info)
    logging.info(
        '创建VM 步骤10-9:拼装所需的镜像信息成功 '
        'task %s : piece together need image info successful when create instance',
        task_id)

    # 发送异步消息到队列
    logging.info(
        '创建VM 步骤10-10:发送异步消息给队列 '
        'task %s : send kafka message start when create instance', task_id)
    data = {
        "routing_key": "INSTANCE.CREATE",
        "send_time": get_datetime_str(),
        "data": {
            "task_id":
            task_id,
            "request_id":
            request_id,
            "host_ip":
            vm_host['ipaddress'],
            "uuid":
            uuid,
            "hostname":
            instance_name,  # 实例名
            "memory_mb":
            flavor_info['memory_mb'],
            "vcpu":
            flavor_info['vcpu'],
            "ostype":
            instance_system,
            "user_id":
            user_id,
            "disks":
            image_list,
            "disk_size":
            vm_disk_gb,
            "image_name":
            _image['url'].split('/')[-1],
            "net_area_id":
            net_area_id,
            "networks": [{
                "net_card_name": "br_bond0." + segment_data['vlan'],
                "ip": data_ip_address,
                "netmask": segment_data['netmask'],
                "dns1": segment_data['dns1'],
                "dns2": segment_data['dns2'],
                "mac": mac,
                "gateway": segment_data['gateway_ip'],
                "env": vm_env  # SIT STG PRD DR
            }]
        }
    }
    ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data)
def instance_msg_send_to_kafka(task_id, request_id):
    '''
        通过传入的task_id, request_id拼凑消息发送kafka,可供外部接口调用
    :param request_id:
    :return:
    '''
    _ins_info = ins_s.InstanceService().get_instance_info_by_requestid(request_id)
    if not _ins_info:
        return logging.error('task %s : can not find instance info '
                             'when retry create instance send kafka msg', task_id)
    if _ins_info['isdeleted'] == '1':
        return logging.error('task %s : instance has been deleted '
                             'when retry create instance send kafka msg', task_id)

    _ins_host_ip = ins_s.get_hostip_of_instance(_ins_info['id'])
    _ins_hostpool_db_info = ins_s.get_hostpool_of_instance(_ins_info['id'])
    _ins_flavor_db_info = ins_s.get_flavor_of_instance(_ins_info['id'])

    if not _ins_host_ip or not _ins_hostpool_db_info or not _ins_flavor_db_info:
        return logging.error('task %s : instance host, hostpool or  flavor information'
                             'when retry create instance send kafka msg', task_id)

    # 获取虚拟机数据盘大小
    ret_disk_status, vm_disk_gb = ins_s.get_data_disk_size_of_instance(_ins_info['id'])
    if not ret_disk_status:
        return logging.error('task %s : instance data disk size can not find'
                             'when retry create instance send kafka msg', task_id)

    # 获取虚拟机对应网段信息
    segment_data = ins_s.get_net_segment_info_of_instance(_ins_info['id'])
    if not segment_data:
        return logging.error('task %s : instance segment information can not find'
                             'when retry create instance send kafka msg', task_id)

    # 获取虚拟机所在机房类型
    vm_env = hostpool_service.get_env_of_hostpool(_ins_hostpool_db_info['id'])
    if not vm_env:
        return logging.error('task %s : instance env information can not find'
                             'when retry create instance send kafka msg', task_id)

    ins_images = ins_s.get_images_of_instance(_ins_info['id'])
    if not ins_images:
        return logging.error('task %s : instance image information can not find'
                             'when retry create instance send kafka msg', task_id)
    else:
        instance_system = ins_images[0]['system']
        image_name = ins_images[0]['name']

    # 获取镜像信息,一个image_name可能对应多个id
    image_nums, image_data = image_service.ImageService().get_images_by_name(image_name)
    if image_nums <= 0:
        return logging.error('task %s : instance image information can not find'
                             'when retry create instance send kafka msg', task_id)

    # 拼装消息需要的镜像信息
    image_list = []
    # 数据盘数量
    data_image_num = 0
    for _image in image_data:
        _image_type = _image['type']
        _info = {
            "disk_format": _image['format'],
            "url": _image['url'],
            "image_size_gb": _image['size_gb']  # 镜像预分配大小
        }
        # 系统盘
        if _image_type == ImageType.SYSTEMDISK:
            _disk_name = _ins_info['name'] + '.img'
            _info['image_dir_path'] = '/app/image/' + _ins_info['uuid'] + '/' + _disk_name
            _info['disk_name'] = _disk_name
            _info['disk_size_gb'] = None
            _info['dev_name'] = 'vda'
        else:
            # 数据盘
            _disk_name = _ins_info['name'] + '.disk' + str(data_image_num + 1)
            _disk_dev_name = _get_vd_map(data_image_num)
            _info['image_dir_path'] = '/app/image/' + _ins_info['uuid'] + '/' + _disk_name
            _info['disk_name'] = _disk_name
            _info['disk_size_gb'] = int(vm_disk_gb)
            _info['dev_name'] = _disk_dev_name
            data_image_num += 1
        image_list.append(_info)

    # 发送异步消息到队列
    data = {
        "routing_key": "INSTANCE.CREATE",
        "send_time": get_datetime_str(),
        "data": {
            "task_id": task_id,
            "request_id": request_id,
            "host_ip": _ins_host_ip,
            "uuid": _ins_info['uuid'],
            "hostname": _ins_info['name'],  # 实例名
            "memory_mb": _ins_flavor_db_info['memory_mb'],
            "vcpu": _ins_flavor_db_info['vcpu'],
            "ostype": instance_system,
            "user_id": _ins_info['owner'],
            "disks": image_list,
            "disk_size": int(vm_disk_gb),
            "image_name": image_name,
            "net_area_id": segment_data['net_area_id'],
            "networks": [
                {
                    "net_card_name": "br_bond0." + segment_data['vlan'],
                    "ip": segment_data['ip_address'],
                    "netmask": segment_data['netmask'],
                    "dns1": segment_data['dns1'],
                    "dns2": segment_data['dns2'],
                    "mac": segment_data['mac'],
                    "gateway": segment_data['gateway_ip'],
                    "env": vm_env  # SIT STG PRD DR
                }
            ]
        }
    }
    ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data)
    # 修改虚拟机状态为创建中
    update_data = {
        'status': VMStatus.CREATING,
        'created_at': get_datetime_str(),
        'updated_at': get_datetime_str()
    }
    where_data = {
        'uuid': _ins_info['uuid']
    }
    ins_s.InstanceService().update_instance_info(update_data, where_data)
    return 'all done'
def instance_msg_send_to_kafka(task_id, request_id):
    '''
        通过传入的task_id, request_id拼凑消息发送kafka,可供外部接口调用
    :param request_id:
    :return:
    '''
    _ins_info = ins_s.InstanceService().get_instance_info_by_requestid(request_id)
    if not _ins_info:
        logging.error('task %s : can not find instance info '
                             'when retry create instance send kafka msg', task_id)
        return False, "can not find instance info", _ins_info['name']

    if _ins_info['isdeleted'] == '1':
        logging.error('task %s : instance has been deleted '
                             'when retry create instance send kafka msg', task_id)
        return False, "instance has been deleted", _ins_info['name']

    _ins_host_ip = ins_s.get_hostip_of_instance(_ins_info['id'])
    _ins_hostpool_db_info = ins_s.get_hostpool_of_instance(_ins_info['id'])
    _ins_flavor_db_info = ins_s.get_flavor_of_instance(_ins_info['id'])

    if not _ins_host_ip or not _ins_hostpool_db_info or not _ins_flavor_db_info:
        logging.error('task %s : instance host, hostpool or  flavor information'
                             'when retry create instance send kafka msg', task_id)
        return False, "instance host, hostpool or  flavor information error", _ins_info['name']

    # 获取虚拟机数据盘大小
    src_instance_sys_disk_size = _ins_flavor_db_info['root_disk_gb']
    data_disk_status, src_instance_data_disk_size = ins_s.get_data_disk_size_of_instance(_ins_info['id'])
    if not data_disk_status:
        logging.error('task %s : instance data disk size can not find'
                             'when retry create instance send kafka msg', task_id)
        return False, "instance data disk size can not find", _ins_info['name']

    src_instance_disk_size = int(src_instance_data_disk_size) + int(src_instance_sys_disk_size)
    _ins_flavor_db_info['src_instance_disk_size'] = src_instance_disk_size
    vm_disk_gb = int(src_instance_disk_size) if int(src_instance_disk_size) > 50 else 50


    # 获取虚拟机对应网段信息
    segment_data = ins_s.get_net_segment_info_of_instance(_ins_info['id'])
    if not segment_data:
        logging.error('task %s : instance segment information can not find'
                             'when retry create instance send kafka msg', task_id)
        return False, "instance segment information can not find", _ins_info['name']

    # 获取虚拟机所在机房类型
    vm_env = hostpool_service.get_env_of_hostpool(_ins_hostpool_db_info['id'])
    if not vm_env:
        logging.error('task %s : instance env information can not find'
                             'when retry create instance send kafka msg', task_id)
        return False, "instance env information can not find", _ins_info['name']

    ins_images = ins_s.get_images_of_instance(_ins_info['id'])
    if not ins_images:
        logging.error('task %s : instance image information can not find'
                             'when retry create instance send kafka msg', task_id)
        return False, "instance image information can not find", _ins_info['name']

    else:
        instance_system = ins_images[0]['system']
        image_name = ins_images[0]['name']

    # 获取镜像信息,一个image_name可能对应多个id
    image_nums, image_data = image_service.ImageService().get_images_by_name(image_name)
    if image_nums <= 0:
        logging.error('task %s : instance image information can not find'
                             'when retry create instance send kafka msg', task_id)
        return False, "instance image information can not find", _ins_info['name']

    #BT源信息获取
    source_ip = _ins_info['clone_source_host']
    source_vm = _ins_info['clone_source_vm']

    #instance相关信息
    instance_id = _ins_info['id']
    uuid = _ins_info['uuid']
    host_id = ins_h_s.get_ins_host_info_by_ins_id(instance_id)['host_id']
    host_ip = ho_s.HostService().get_host_info(host_id)['ipaddress']
    instance_name = _ins_info['name']



    #获取source_disk_list
    source_instance_info = ins_s.InstanceService().get_instance_info_by_name(source_vm)
    if not source_instance_info:
        logging.info('克隆源vm %s 不存在' % source_vm)
        return False, "克隆源vm %s 不存在" % source_vm

    source_instance_id = source_instance_info['id']
    instance_clone_create_data = ins_c_c.get_ins_clone_create_info_by_task_id(task_id)
    if not instance_clone_create_data:
        logging.info('获取克隆创建源vm信息失败')
        return False, "获取克隆创建源vm信息失败"

    clone_image_num = instance_clone_create_data['torrent_num']
    source_disk_list = []
    for i in range(int(clone_image_num)):
        clone_image_name = source_vm + '_' + task_id + '_' + str(i)
        source_disk_list.append(clone_image_name)

    # 获取源vm的镜像名称
    sour_instance_image = ins_i_s.get_ins_image_info_by_ins_id(source_instance_id)
    total_size = instance_clone_create_data["total_size"]
    trans_type = instance_clone_create_data["trans_type"]
    http_port = instance_clone_create_data["http_port"]
    md5_check = instance_clone_create_data["md5_check"]
    sour_image_id = sour_instance_image['image_id']
    sour_image_data = image_service.ImageService().get_image_info(sour_image_id)
    image_name = sour_image_data['name']





    # 发送异步消息到队列
    data = {
        "routing_key": "INSTANCE.CLONECREATE",
        "send_time": get_datetime_str(),
        "data": {
            "task_id": task_id,
            "source_ip":source_ip,
            "request_id": request_id,
            "instance_id":instance_id,
            "host_ip": host_ip,
            "uuid": uuid,
            "trans_type": trans_type,
            "http_port": http_port,
            "md5_check": md5_check,
            'source_vm':source_vm,
            "hostname": instance_name,  # 实例名
            "memory_mb": _ins_flavor_db_info['memory_mb'],
            "vcpu": _ins_flavor_db_info['vcpu'],
            "ostype": instance_system,
            "user_id": _ins_info['owner'],
            "clone_image_num": clone_image_num,
            "disks":source_disk_list,
            "total_size": total_size,
            "image_name": image_name,
            "net_area_id": segment_data['net_area_id'],
            "networks": [
                {
                    "net_card_name": "br_bond0." + segment_data['vlan'],
                    "ip": segment_data['ip_address'],
                    "netmask": segment_data['netmask'],
                    "dns1": segment_data['dns1'],
                    "dns2": segment_data['dns2'],
                    "mac": segment_data['mac'],
                    "gateway": segment_data['gateway_ip'],
                    "env": vm_env  # SIT STG PRD DR
                }
            ]
        }
    }
    ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data)
    # 修改虚拟机状态为创建中
    update_data = {
        'status': VMStatus.CREATING,
        'created_at': get_datetime_str(),
        'updated_at': get_datetime_str()
    }
    where_data = {
        'uuid': _ins_info['uuid']
    }
    ins_s.InstanceService().update_instance_info(update_data, where_data)
    return 'done'