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'
示例#2
0
def console():
    """
    虚拟机vnc控制台
    :param instance_id:
    :return :
    """
    """
    if not instance_id:
        logging.info('no instance id when get configure info')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误")

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)
    host_ip = ins_s.get_hostip_of_instance(instance_id)
    if not ins_data or not host_ip:
        logging.info('instance %s data is no exist in db when get configure info', instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    instance_name = ins_data['name']

    connect_disk_device_get = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=instance_name)
    # result, data = vmManager.libvirt_get_vnc_port(connect_disk_device_get, instance_name)
    # if not result:
        # logging.info(data)
        # return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    """
    console_server_host = request.host.split(':')[0]
    apple = request.query_string.decode().strip()
    peeledapple = apple.split('=')
    instance_uuid = peeledapple[1]
    if not instance_uuid or not console_server_host:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)
    ins_info = InstanceService().get_instance_info_by_uuid(instance_uuid)
    if not ins_info:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)
    kvm_host_ip = get_hostip_of_instance(ins_info['id'])
    if not kvm_host_ip:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    # 连接libvirtd查询虚拟机console端口号
    connect_instance = vmManager.libvirt_get_connect(kvm_host_ip,
                                                     conn_type='instance',
                                                     vmname=ins_info['name'])
    status, vnc_port = vmManager.libvirt_get_vnc_console(
        connect_instance, ins_info['name'])
    if not status:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    token = str(kvm_host_ip) + '-' + str(vnc_port)
    resp = make_response(
        render_template('console-vnc.html',
                        vm_name=ins_info['name'],
                        ws_host=console_server_host,
                        ws_port=6080))
    resp.set_cookie('token', token)
    # 添加操作记录: try.. except .. 部分
    try:
        user = user_service.get_user()
        extra_data = "name:" + ins_info['name'] + "," + "uuid:" + peeledapple[1]
        add_operation_other(user["user_id"], OperationObject.VM,
                            OperationAction.CONSOLE, "SUCCESS", extra_data)
    except:
        pass
    return resp
def instance_disk_config(msg_data):
    logging.info("--" * 25)
    logging.info(msg_data)
    msg = json_helper.read(msg_data)
    data = msg.get('data')
    user_id = data.get('user_id')
    request_id = data.get('request_id')
    instance_id = data.get('instance_id')
    vm_uuid = data.get('uuid')
    disks = data.get('disk_msg')
    if request_id is None or instance_id is None:
        return 1
    instance_info = InstanceService().get_instance_info(instance_id)
    for disk in disks:
        # 查看虚拟机mount所在磁盘位置、磁盘当前大小,vg、lv名称
        host_ip = get_hostip_of_instance(instance_id)
        mount_point = disk['mount_point']
        if mount_point and host_ip and instance_info['name']:
            vm_name = instance_info['name']
            status, disk_path, disk_size, vm_vg_lv, _message = _check_volume_is_existed_and_volume_size(
                host_ip, vm_uuid, vm_name, mount_point, request_id, user_id)
            if status:
                if disk['size_gb'] <= disk_size:
                    logging.info('disk size user input less than now, failed')
                else:
                    add_instance_actions(vm_uuid, request_id, user_id,
                                         InstaceActions.INSTANCE_DISK_RESIZE,
                                         'start')
                    connect_disk_resize = vmManager.libvirt_get_connect(
                        host_ip, conn_type='instance', vmname=vm_name)
                    disk_resize_status, disk_resize_msg = vmManager.libvirt_config_disk_resize(
                        connect_disk_resize, disk_path, int(disk['size_gb']))
                    logging.info(disk_resize_msg)
                    if disk_resize_status:
                        instance_disk_resize_status = ActionStatus.SUCCSESS
                        _message = 'instance %s disk %s resize successful' % (
                            vm_name, disk_path)
                        update_instance_actions(
                            vm_uuid, request_id, user_id,
                            InstaceActions.INSTANCE_DISK_RESIZE,
                            instance_disk_resize_status, _message)
                        print 'start to get disk dev:'
                        add_instance_actions(
                            vm_uuid, request_id, user_id,
                            InstaceActions.INSTANCE_DISK_DEVICE, 'start')
                        connect_disk_device_get = vmManager.libvirt_get_connect(
                            host_ip, conn_type='instance', vmname=vm_name)
                        disk_device_status, disk_dev = vmManager.libvirt_get_disk_device_by_path(
                            connect_disk_device_get, disk_path)
                        logging.info('disk device is: ' + disk_dev)
                        if disk_device_status:
                            instance_disk_device_status = ActionStatus.SUCCSESS
                            _message = 'instance %s disk device get successful, device name is %s' % (
                                vm_name, disk_dev)
                            update_instance_actions(
                                vm_uuid, request_id, user_id,
                                InstaceActions.INSTANCE_DISK_DEVICE,
                                instance_disk_device_status, _message)
                            # 查看虚拟机状态
                            add_instance_actions(
                                vm_uuid, request_id, user_id,
                                InstaceActions.INSTANCE_STATUS_CHECK, 'start')
                            print 'start to check instance %s status' % instance_id
                            instance_info = InstanceService(
                            ).get_instance_info(instance_id)
                            if instance_info['status'] == '3':
                                instance_status = ActionStatus.SUCCSESS
                                _message = 'instance %s is running' % vm_name
                                update_instance_actions(
                                    vm_uuid, request_id, user_id,
                                    InstaceActions.INSTANCE_STATUS_CHECK,
                                    instance_status, _message)
                                add_instance_actions(
                                    vm_uuid, request_id, user_id,
                                    InstaceActions.INSTANCE_DISK_INJECT_TO_OS,
                                    'start')
                                # 下发qemu agent命令
                                connect_disk_inject = vmManager.libvirt_get_connect(
                                    host_ip,
                                    conn_type='instance',
                                    vmname=vm_name)
                                disk_add_size = str(
                                    int(disk['size_gb']) - int(disk_size) - 1)
                                inject_disk_stauts, result_msg = vmManager.libvirt_inject_resize_disk(
                                    connect_disk_inject, disk_dev, vm_vg_lv,
                                    disk_add_size)
                                logging.info(result_msg)
                                if inject_disk_stauts:
                                    instance_disk_inject_on_os_status = ActionStatus.SUCCSESS
                                    _message = 'instance %s disk resize on os successful' % vm_name
                                    update_instance_actions(
                                        vm_uuid, request_id, user_id,
                                        InstaceActions.
                                        INSTANCE_DISK_INJECT_TO_OS,
                                        instance_disk_inject_on_os_status,
                                        _message)
                                    # 修改数据库虚拟机磁盘大小
                                    update_data = {
                                        'size_gb': disk['size_gb'],
                                        'updated_at': get_datetime_str()
                                    }
                                    where_data = {
                                        'instance_id': instance_id,
                                        'mount_point': mount_point
                                    }
                                    ret = ins_d_s.InstanceDiskService(
                                    ).update_instance_disk_info(
                                        update_data, where_data)
                                else:
                                    instance_disk_inject_on_os_status = ActionStatus.FAILD
                                    _message = 'instance %s disk resize on os failed because %s' % (
                                        vm_name, result_msg)
                                    update_instance_actions(
                                        vm_uuid, request_id, user_id,
                                        InstaceActions.
                                        INSTANCE_DISK_INJECT_TO_OS,
                                        instance_disk_inject_on_os_status,
                                        _message)
                            else:
                                instance_status = ActionStatus.FAILD
                                _message = 'failed: instance %s not running' % vm_name
                                update_instance_actions(
                                    vm_uuid, request_id, user_id,
                                    InstaceActions.INSTANCE_STATUS_CHECK,
                                    instance_status, _message)
                        else:
                            instance_disk_device_status = ActionStatus.FAILD
                            _message = 'instance %s disk device get failed' % vm_name
                            update_instance_actions(
                                vm_uuid, request_id, user_id,
                                InstaceActions.INSTANCE_DISK_DEVICE,
                                instance_disk_device_status, _message)
                    else:
                        instance_disk_resize_status = ActionStatus.FAILD
                        _message = 'instance %s disk %s resize faile because %s' % (
                            vm_name, disk_path, disk_resize_msg)
                        update_instance_actions(
                            vm_uuid, request_id, user_id,
                            InstaceActions.INSTANCE_DISK_RESIZE,
                            instance_disk_resize_status, _message)
            else:
                logging.info(_message)
    return 'all job done, check whether has error in database instance'
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'
示例#5
0
def extend_disk(instance_id):
    """
      扩展磁盘接口
    :param instance_id:
    :return:
    """
    c_system = ''
    c_version = None
    qemu_ga_update = False
    mount_point_list = []

    if not instance_id:
        logging.info('no instance id when get configure info')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误")

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)
    uuid = ins_data['uuid']
    user_id = get_user()['user_id']
    request_id = ins_s.generate_req_id()

    host_ip = ins_s.get_hostip_of_instance(instance_id)

    if not ins_data or not host_ip:
        data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update}
        logging.info('instance %s data is no exist in db when get configure info', instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, data=data_params, msg='数据库查询错误')

    if ins_data['create_source'] == '0':
        ins_images_data = ins_s.get_images_of_instance(instance_id)

        if ins_images_data:
            c_system = ins_images_data[0]['system']
            c_version = ins_images_data[0]['version']
    else:
        ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id)
        if ins_images_data:
            c_system = ins_images_data['os_type']
            if ins_images_data['os_version'] and '6.6' in ins_images_data['os_version']:
                c_version = '6.6'
            elif ins_images_data['os_version'] and '7.2' in ins_images_data['os_version']:
                c_version = '7.2'

    # 更新qemu-guest-agent action到数据库,zitong wang 29th,9,2017
    ins_a_s.add_disk_display_action_to_database(uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY,
                                        ActionStatus.START, 'start')

    # 更新qemu-guest-agent,获取所有挂载点的信息,add by zitongwang in 21th,9,2017
    if c_system == "linux" and c_version:
        c_version = CentOS_Version.CentOS_7 if c_version >= '7.0' else CentOS_Version.CentOS_6
        ins_a_s.add_disk_display_action_to_database(uuid, request_id, user_id,
                                            InstaceActions.INSTANCE_UPDATE_QEMU_AGENT, ActionStatus.START, 'start')
        # 更新qemu-ga版本
        vmManager.update_qemu_ga_instance(c_version,host_ip,ins_data['name'])
        connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name'])
        if not connect_instance:
            data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update}
            msg = "libvirt连接建立失败,无法使用libvirt管理虚拟机"
            ins_a_s.add_disk_display_action_to_database(uuid, request_id, ActionStatus.FAILD,
                                                InstaceActions.INSTANCE_LIBVIRT_ERROR, msg)
            return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, data=data_params, msg=msg)

        # 重新建立连接判断是否更新成功
        flag, msg = connect_instance.test_update_command()
        qemu_ga_update = flag
        if flag:
            # 更新action数据库状态:更新成功
            _message = "qemu_agent update successfully"
            ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT,
                                                   ActionStatus.SUCCSESS, _message)

            # 针对v2v机器,pvs显示的LV名称有问题
            connect_instance.exec_qemu_command("pvscan")

            # 获得所有挂载点信息
            command = "lsblk -r | awk '{print $7}' | awk NF | grep  '^/' | grep -v '^/boot'"
            flag, msg = connect_instance.exec_qemu_command(command)
            mount_point = msg.splitlines()
            # 获取挂载点文件系统,大小,类型,挂载点信息
            command = "lsblk -r | awk '{print $1" + "\\\" " + "\\\"" + "$4" + "\\\" " + "\\\"" + "$6" + "\\\" " + "\\\"" + "$7}'"
            flag, msg = connect_instance.exec_qemu_command(command)
            parts_info = msg.split('\n')
            parts_info.pop()

            mount_point_list = []
            mount_list = []
            for mount in mount_point:
                disk_info = {}

                mount_data = filter(lambda x: x.split(' ')[-1] == mount, parts_info)
                data = mount_data[0].split(' ')
                disk_info['mount_point'] = data[-1]

                # 存在数据就返回
                if disk_info['mount_point'] in mount_list:
                    continue
                else:
                    mount_list.append(disk_info['mount_point'])
                disk_info['mount_partition_name'] = data[0]
                disk_info['mount_point_size'] = float(data[1][0:-1]) if data[1][-1].endswith('G') else float(
                    data[1][0:-1]) / 1024
                disk_info['mount_partition_type'] = data[2]
                command = "df -P '%s'| awk 'NR==2 {print $5}'" % mount
                flag, msg = connect_instance.exec_qemu_command(command)
                disk_info['mount_point_use'] = msg.strip()

                mount_point_list.append(disk_info)
            data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update}

            _message = "linux os disk information display successfully"
            ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY,
                                                   ActionStatus.SUCCSESS, _message)
            return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                               data=data_params)
        else:
            # 更新qmeu-ga失败
            _message = "qemu_agent update failed"
            ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT,
                                                   ActionStatus.FAILD, _message)
            data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update}
            return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL,
                                               data=data_params, msg='qemu update fail')
    elif c_system == "windows":
        connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name'])
        disk_info = connect_instance.get_configure_disk_device(uuid)
        storage_instance = vmManager.libvirt_get_connect(host_ip, conn_type='storage', vmname=ins_data['name'],
                                                         poolname=uuid)
        mount_point_list = []
        for x in disk_info:
            d = {}
            block_info = storage_instance.get_disk_size(x['image'])
            d.setdefault('mount_point', x['dev'])
            d.setdefault('mount_point_size', '%.1f' % (float(block_info[0]) / 1073741824))
            d.setdefault('mount_point_use', '%.2f' % (float(block_info[1]) / block_info[0] * 100))
            d.setdefault('mount_partition_name', "")
            d.setdefault('mount_partition_type', "")
            mount_point_list.append(d)

        qemu_ga_update = True
        data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update}
        _message = "disk information display successfully"
        ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY,
                                               ActionStatus.SUCCSESS, _message)
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                           data=data_params, msg=_message)
    else:
        data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update}
        _message = "os type unknown, please call kvm administrators"
        ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY,
                                               ActionStatus.FAILD, _message)
        return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL,
                                           data=data_params, msg=_message)
示例#6
0
def configure_init(instance_id):
    '''
        修改配置时获取初始数据
    :param instance_id:
    :return:
    '''
    if not instance_id:
        logging.info('no instance id when get configure info')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误")

    resp = ConfigureInitInfoResp()

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)

    host_ip = ins_s.get_hostip_of_instance(instance_id)
    if not ins_data or not host_ip:
        logging.info('instance %s data is no exist in db when get configure info', instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    resp.c_instance_name = ins_data['name']
    resp.c_app_info = ins_data['app_info']
    resp.c_owner = ins_data['owner']
    ins_status = ins_data['status']
    if ins_status != VMStatus.STARTUP and ins_status != VMStatus.SHUTDOWN:
        logging.error('instance status %s is invalid when get instance configure init info', ins_status)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='只能在开机或关机状态下修改配置')

    if ins_data['create_source'] == '0':
        ins_images_data = ins_s.get_images_of_instance(instance_id)

        if ins_images_data:
            resp.c_system = ins_images_data[0]['system']
    else:
        ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id)
        if ins_images_data:
            resp.c_system = ins_images_data['os_type']

    """
    ins_disks_data = ins_s.get_disks_of_instance(instance_id)
    if not ins_disks_data:
        logging.error('instance %s has no disk info when change instance configure', instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 关机状态、windows系统都不能修改数据盘
    if ins_status != VMStatus.SHUTDOWN and resp.c_system == 'linux':
        for _disk in ins_disks_data:
            _disk_info = {
                'size_gb': _disk['size_gb'],
                'mount_point': _disk['mount_point']
            }
            resp.c_disk_gb_list.append(_disk_info)
    """

    ins_flavor_data = ins_s.get_flavor_of_instance(instance_id)
    if not ins_flavor_data:
        logging.error('instance %s has no flavor info when change instance configure', instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    resp.c_flavor_id = ins_flavor_data['flavor_id']

    # flavor信息
    flavors_nums, flavors_data = fla_s.FlavorService().get_all_flavors()
    for _flavor in flavors_data:
        # 系统盘容量不能修改
        if _flavor['root_disk_gb'] == ins_flavor_data['root_disk_gb']:
            # 开机状态不能修改内存
            if ins_status == VMStatus.STARTUP:
                if _flavor['memory_mb'] == ins_flavor_data['memory_mb']:
                    _flavor_info = flavor_init_info.FlavorInitInfo().init_from_db(_flavor)
                    resp.flavors.append(_flavor_info)
            else:
                _flavor_info = flavor_init_info.FlavorInitInfo().init_from_db(_flavor)
                resp.flavors.append(_flavor_info)

    ins_group_data = ins_s.get_group_of_instance(instance_id)
    if ins_group_data:
        resp.c_group_id = ins_group_data['group_id']

    # user_group_ids_list = current_user_group_ids()
    # # 超级管理员组
    # if 1 in user_group_ids_list:
    #     is_super_group = True
    # else:
    #     is_super_group = False

    # group信息
    user_groups = current_user_groups()
    user_group_ids_list = []
    is_super_group = False
    for _groups in user_groups:
        user_group_ids_list.append(_groups['id'])
        # 超级管理员组
        if _groups['name'] == "supergroup":
            is_super_group = True

    # group信息
    groups_params = {
        'WHERE_AND': {
            '=': {
                'dc_type': ins_group_data['dc_type'],
                'isdeleted': '0'
            }
        },
    }
    groups_nums, groups_data = group_s.GroupService().query_data(**groups_params)
    for _group in groups_data:
        # 管理员组的成员可以显示所有组,而非管理员组的只显示当前用户所在应用组
        if not is_super_group and _group['id'] not in user_group_ids_list:
            continue

        _group_info = {
            'group_id': _group['id'],
            'group_name': _group['name']
        }
        resp.groups.append(_group_info)

    # 连接libvirtd查询虚拟机网卡状态信息
    _net_online = []
    _net_offline = []
    _libvirt_net_ret, _libvirt_net_info = vmManager.libvirt_get_netcard_state(host_ip, ins_data['name'])
    if _libvirt_net_ret != 0:
        _nic_status = False
    else:
        _nic_status = True
        for _p_libvirt_net_info in _libvirt_net_info:
            if _p_libvirt_net_info['state'] == NetCardStatus.UP:
                _net_online.append(_p_libvirt_net_info['mac'])
            else:
                _net_offline.append(_p_libvirt_net_info['mac'])

    # 虚拟机网卡信息返回前端
    _db_net_card_data = ins_s.get_net_info_of_instance(instance_id)
    if _db_net_card_data:
        for _p_db_net_card_data in _db_net_card_data:
            if not _nic_status:
                _p_ins_nic_status = ''
            else:
                if _p_db_net_card_data['mac'] in _net_online:
                    _p_ins_nic_status = '1'
                elif _p_db_net_card_data['mac'] in _net_offline:
                    _p_ins_nic_status = '0'
                else:
                    _p_ins_nic_status = '2'
            if not _p_db_net_card_data['segment_type']:
                _ip_type = '-1'
            else:
                _ip_type = _p_db_net_card_data['segment_type']
            _i_net_info = {
                'ip_addr': _p_db_net_card_data['ip_address'],
                'vlan': _p_db_net_card_data['vlan'],
                'mac_addr': _p_db_net_card_data['mac'],
                'nic_status': _p_ins_nic_status,
                'ip_type': _ip_type,
                'nic_type': _p_db_net_card_data['nic_type']
            }
            resp.c_net.append(_i_net_info)

    # 获取虚拟机所在网络区域下所有ip信息
    resp.c_ips = []
    ins_netarea_info = ins_s.get_netarea_of_instance(instance_id)
    ins_datacenter_info = ins_s.get_datacenter_of_instance(instance_id)
    if ins_datacenter_info and ins_datacenter_info['dc_type']:
        if ins_netarea_info and ins_netarea_info['id']:
            ip_segment_num, ip_segment_datas = ip_segment_s().get_segment_datas_in_net_area(ins_netarea_info['id'])
            if ip_segment_num > 0:
                # 获取可用ip
                ips_available = ip_service.get_all_available_ips(ip_segment_datas, ins_datacenter_info['dc_type'])
                if len(ips_available) > 0:
                    ip_list = []
                    for ip_info in ips_available:
                        ip_params = {
                            "value": ip_info['ip_address'],
                            "vlan": ip_info['vlan'],
                            "ip_type": ip_info['ip_type']
                        }
                        ip_list.append(ip_params)
                    resp.c_ips = ip_list

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
示例#7
0
def instance_configure(instance_id):
    '''
        虚机修改配置
        规则:
            热修改(开机状态):cpu disk 加
            冷修改(关机状态):cpu mem 加减  disk 加
    :param instance_id:
    :return:
    '''
    n_flavor_id = request.values.get('flavor_id')
    n_app_info = request.values.get('app_info')
    n_owner = request.values.get('owner')
    n_group_id = request.values.get('group_id')
    n_net_conf_list_req = request.values.get('net_status_list')

    # start
    n_extend_list_req = request.values.get('extend_list')
    n_qemu_ga_update_req = request.values.get('qemu_ga_update')
    c_system = ''
    c_version = None
    # end

    if not instance_id or not n_flavor_id or not n_group_id:
        logging.error('params is invalid when change instance configure')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)

    ###################################add 2017/09/29#############################3
    uuid = ins_data['uuid']
    user_id = get_user()['user_id']
    request_id = ins_s.generate_req_id()

    if not ins_data:
        logging.error('the instance %s is not exist in db when change instance configure', instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    # --------------------edit 2017/11/13-----------------------
    if ins_data['create_source'] == '0':
        ins_images_data = ins_s.get_images_of_instance(instance_id)

        if ins_images_data:
            c_system = ins_images_data[0]['system']
    else:
        ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id)
        if ins_images_data:
            c_system = ins_images_data['os_type']

    ins_status = ins_data['status']

    # 获取虚拟机所在物理机信息
    host_data = ins_s.get_host_of_instance(instance_id)
    ins_datacenter_info = ins_s.get_datacenter_of_instance(instance_id)
    if not host_data or not ins_datacenter_info:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法获取虚拟机所在物理机信息、机房信息")

    ins_data['dc_type'] = ins_datacenter_info['dc_type']

    # 新flavor信息
    n_flavor_data = fla_s.FlavorService().get_flavor_info(n_flavor_id)
    if not n_flavor_data:
        logging.error('flavor %s is invalid in db when change instance configure', n_flavor_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='新的配置数据有误,无法修改配置')

    # 虚机现有flavor信息
    c_flavor_data = ins_s.get_flavor_of_instance(instance_id)
    if not c_flavor_data:
        logging.error('instance %s flavor is invalid in db when change instance configure', instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    c_group_data = ins_s.get_group_of_instance(instance_id)
    if c_group_data and int(c_group_data['group_id']) != int(n_group_id):
        # 检查新应用组的配额
        is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data)
        if not is_group_enough:
            logging.error('new group %s quota is not enough to change new flavor', n_group_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg)

    params = {}

    if json_helper.loads(n_extend_list_req):

        # 检查当前应用组的配额
        is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data,
                                                             json_helper.loads(n_extend_list_req))
        if not is_group_enough:
            logging.error('new group %s quota is not enough to change new flavor', n_group_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg)

        # 检查物理机当前使用率情况是否满足扩容
        is_host_available, ret_msg = __check_host_capacity(host_data, n_flavor_data, c_flavor_data
                                                           , json_helper.loads(n_extend_list_req))
        if not is_host_available:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_msg)

        vmname = ins_data['name']
        uuid = ''
        host_ip = ''
        n_extend_list_req = json_helper.loads(n_extend_list_req)
        try:
            uuid = ins_data['uuid']
            host_ip = ins_s.get_hostip_of_instance(instance_id)
        except:
            pass

        connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name'])
        if not connect_instance:
            pass
        # 添加扩容开始action
        ins_a_s.update_instance_status(VMStatus.CONFIGURE_ING, instance_id)
        ins_a_s.add_disk_extend_action_to_database(uuid, request_id, user_id,
                                                   InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.START, 'start')
        # 满足扩容条件
        if n_qemu_ga_update_req:
            if c_system.strip() == 'linux':
                flag, msg = connect_instance.exec_qemu_command(
                    "cat /proc/self/mounts | grep -w / | grep -v rootfs | awk '{print $3}'")
                if not flag:
                    c_version = None
                c_version = CentOS_Version.CentOS_6 if msg.strip() == 'ext4' else CentOS_Version.CentOS_7
                flag, result = ins_a_s.extend_mount_size(n_extend_list_req, host_ip, vmname, uuid, c_version, instance_id)
            elif c_system.strip() == 'windows':
                flag, result = ins_a_s.extend_dev_size(n_extend_list_req, host_ip, vmname, uuid, instance_id)
            else:
                flag = False
            if flag:
                msg = "扩容成功"
                ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND,
                                                       ActionStatus.SUCCSESS, msg)
                ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
            else:
                msg = "扩容失败,{}".format(result)
                ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND,
                                                       ActionStatus.FAILD, msg)
                ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
                return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg=msg)
        else :
            # 非linux系统,关机状态,qemu-guest-agent没有更新成功
            msg = "非linux系统,扩容失败"
            ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.FAILD,
                                                   msg)
            ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
            return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg=msg)
    else:
        pass

    if c_flavor_data['vcpu'] != n_flavor_data['vcpu'] or c_flavor_data['memory_mb'] != n_flavor_data['memory_mb']:

        # 检查当前应用组的配额
        is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data)
        if not is_group_enough:
            logging.error('new group %s quota is not enough to change new flavor', n_group_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg)

        # 检查物理机当前使用率情况是否满足扩容
        is_host_available, ret_msg = __check_host_capacity(host_data, n_flavor_data, c_flavor_data)
        if not is_host_available:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_msg)

        # 关机状态
        if ins_status == VMStatus.SHUTDOWN:
            pass
        elif ins_status == VMStatus.STARTUP:
            # 开机状态
            # cpu只能增
            if c_flavor_data['vcpu'] > n_flavor_data['vcpu']:
                logging.error('vcpu only be increase in startup status, now vcpu %s > new vcpu %s',
                              c_flavor_data['vcpu'], n_flavor_data['vcpu'])
                ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='开机状态下,CPU数量只能增加不能减少')

            # 内存不能修改
            if c_flavor_data['memory_mb'] != n_flavor_data['memory_mb']:
                logging.error('memory only no allow be change in startup status, now mem %s, new mem %s',
                              c_flavor_data['memory_mb'], n_flavor_data['memory_mb'])
                ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='开机状态下,不能修改内存容量')
        else:
            logging.error('instance status %s is invalid when change instance configure', ins_status)
            ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='只能在开机或关机状态下修改配置')

    if n_flavor_data['vcpu'] == c_flavor_data['vcpu']:
        pass
    else:
        params['new_vcpu'] = n_flavor_data['vcpu']
        params['old_vcpu'] = c_flavor_data['vcpu']

    new_mem = n_flavor_data['memory_mb']
    old_mem = c_flavor_data['memory_mb']

    if new_mem == old_mem:
        pass
    else:
        # 检查内存是否超分
        if not _check_mem_allocation(instance_id, new_mem, old_mem):
            logging.error('instance %s mem has over allocation, new mem %s, old mem %s', instance_id, new_mem, old_mem)
            ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='物理内存不能超分')
        params['new_mem'] = new_mem
        params['old_mem'] = old_mem

    # 检查网络配置是否需要修改
    n_net_conf_list = json_helper.loads(n_net_conf_list_req)
    if n_net_conf_list:
        params['net_status_list'] = n_net_conf_list

    # 没有一个指标可以修改
    if not params:
        logging.error('vcpu, mem, disk no one can change when change instance configure')
    else:
        host_ip = ins_s.get_hostip_of_instance(ins_data['id'])
        if not host_ip:
            logging.error('instance %s has no host ip when change instance configure', ins_data['id'])
            ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

        ret_flavor = ins_a_s.change_instance_configure(host_ip, ins_data, c_flavor_data['flavor_id'], n_flavor_id,
                                                       ins_status, **params)
        if not ret_flavor:
            ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    update_data_i = {
        'app_info': n_app_info,
        'owner': n_owner,
        'updated_at': get_datetime_str()
    }
    where_data_i = {
        'id': instance_id
    }
    ret_i = ins_s.InstanceService().update_instance_info(update_data_i, where_data_i)
    # if ret_i != 1:
    #     logging.error('update instance info error when configure, update_data:%s, where_data:%s',
    #                   update_data_i, where_data_i)
    #     return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    update_data_g = {
        'group_id': n_group_id,
        'updated_at': get_datetime_str()
    }
    where_data_g = {
        'instance_id': instance_id
    }
    ret_g = ins_g_s.InstanceGroupService().update_instance_group_info(update_data_g, where_data_g)
    # if ret_g != 1:
    #     logging.error('update group info error when configure, update_data:%s, where_data:%s',
    #                   update_data_g, where_data_g)
    #     return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # if 'disk_gb_list' in params:
    #    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg='硬盘扩容任务发送成功')

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg='修改配置成功')