Ejemplo n.º 1
0
def instance_status_change_for_miniarch():
    '''
        修改虚拟机状态为v2v中,或者关机中
    :return:
    '''
    instance_uuid = request.values.get('instance_uuid')
    instance_status = request.values.get('instance_status')
    if not instance_uuid or not instance_status:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg="请求入参缺失")

    if instance_status not in [VMStatus.MINIARCH_MIGRATE, VMStatus.SHUTDOWN]:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="待修改的虚拟机状态无法识别")

    ins_data = instance_s.InstanceService().get_instance_info_by_uuid(
        instance_uuid)
    if not ins_data:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="无法获取虚拟机信息")

    # 将克隆源vm状态改成关机
    where_data = {'uuid': instance_uuid}
    update_data = {'status': instance_status}
    ret_change_vm_status = instance_s.InstanceService().update_instance_info(
        update_data, where_data)
    if ret_change_vm_status < 1:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="虚拟机状态更新失败")

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg="虚拟机状态更新成功")
Ejemplo n.º 2
0
def instance_add_netcard(instance_id):
    '''
        kvm平台虚拟机添加网卡接口
    :param instance_id:
    :return:
    '''
    # 判断指定虚拟机是否存在
    if not instance_id:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="instance_id为空,添加网卡失败")

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)
    if not ins_data:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="无法找到待添加网卡虚拟机")

    # 查询指定虚拟机网卡数量,目前不能超过3块
    instance_net_card = ins_s.get_net_info_of_instance(instance_id)
    if instance_net_card:
        if len(instance_net_card) >= INSTANCE_NETCARD_NUMS:
            return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="虚拟机网卡数量不能超过%s张" % str(INSTANCE_NETCARD_NUMS))

    # 往instance_ip表添加记录
    mac = randomMAC()
    instance_ip_data = {
        'instance_id': instance_id,
        'mac': mac,
        'type': InstanceNicType.NORMAL_NETWORK_NIC,
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret_add = ins_ip_s.InstanceIPService().add_instance_ip_info(instance_ip_data)
    if ret_add.get('row_num') <= 0:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="虚拟机网卡创建失败")

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg="虚拟机网卡创建成功")
Ejemplo n.º 3
0
def instance_retry_create(request_id_list):
    '''
        虚拟机重新创建,通过request_id重新发送kafka消息
    :return:
    '''
    threads = []
    req_ids = request_id_list
    #req_ids = request.values.get('request_ids')
    if not req_ids:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    req_ids_list = req_ids.split(',')
    for req_id in req_ids_list:
        ins_info = ins_s.InstanceService().get_instance_info_by_requestid(req_id)
        if ins_info:
            if ins_info['status'] != '100':
                continue
            kafka_send_thread = threading.Thread(target=instance_msg_send_to_kafka, args=(ins_info['task_id'], req_id,))
            threads.append(kafka_send_thread)
            kafka_send_thread.start()

    # 判断多线程是否结束
    if len(threads) == 0:
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data='没有找到需要重试的虚拟机')

    for t in threads:
        t.join()
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Ejemplo n.º 4
0
def rename_vm_disk(src_image_list, host_ip, request_id, uuid, user_id,
                   instance_id):
    instance_data = ins_s.InstanceService().get_instance_info(instance_id)
    instance_name = instance_data['name']
    ret_check_status, job_status = _check_job_step_done(
        request_id, InstaceActions.INSTANCE_CLONE_RENAME_IMAGES)
    if ret_check_status and job_status is 1:
        message = "pass"
        # logging.info(message)
        return ActionStatus.SUCCSESS, message
    else:
        _add_instance_actions(uuid, request_id, user_id,
                              InstaceActions.INSTANCE_CLONE_RENAME_IMAGES,
                              'start')
        for image in src_image_list:
            image_tag = image.split('.', 1)
            new_im_name = instance_name + '.' + image_tag[1]
            dest_dir = '/app/image/' + uuid
            res_rename, message = ansibleCmdV2.rename_clone_image(
                host_ip, image, new_im_name, dest_dir)
            if not res_rename:
                status = ActionStatus.FAILD
                message = '重命名 %s 磁盘文件时失败' % image
                _update_instance_actions(
                    uuid, request_id, user_id,
                    InstaceActions.INSTANCE_CLONE_RENAME_IMAGES, status,
                    message)
                return status, message
        status = ActionStatus.SUCCSESS
        message = '重命名磁盘文件成功'
        _update_instance_actions(uuid, request_id, user_id,
                                 InstaceActions.INSTANCE_CLONE_RENAME_IMAGES,
                                 status, message)
        return status, message
Ejemplo n.º 5
0
def instance_startup():
    '''
        虚机开机
    :return:
    '''
    ins_ids = request.values.get('instance_ids')
    if not ins_ids:
        logging.info('no instance_ids when startup instance')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_ids_list = ins_ids.split(',')
    # 操作的instance数
    all_num = len(ins_ids_list)
    if all_num > int(INSTANCE_MAX_STARTUP):
        logging.info('startup nums %s is greater than max %s', all_num,
                     INSTANCE_MAX_STARTUP)
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    msg = None
    fail_num = 0
    for _ins_id in ins_ids_list:
        _ins_data = ins_s.InstanceService().get_instance_info(_ins_id)
        if _ins_data:
            # 本身是开机状态的不能再开机
            if _ins_data['status'] == VMStatus.STARTUP or _ins_data[
                    'status'] == VMStatus.STARTUP_ING:
                logging.info(
                    'the instance status %s is invalid when startup instance',
                    _ins_data['status'])
                fail_num += 1
                # 单台操作且已失败则直接跳出循环
                if all_num == 1:
                    msg = '该虚拟机已经开机,请勿重复开机'
                    break
                continue
            else:
                _ret_start = ins_a_s.startup_instance(_ins_data)
                if not _ret_start:
                    fail_num += 1
                    continue
        else:
            logging.info(
                'the instance is not exist in db when startup instance')
            fail_num += 1
            continue

    # 全失败
    if fail_num == all_num:
        logging.error("startup instance all failed")
        if msg:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("startup instance part failed")
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分虚拟机开机成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Ejemplo n.º 6
0
def _vm_disk_snapshot_commit(task_id, uuid, user_id, request_id, source_host,
                             src_instance_id, disk_tag_list):
    ret_check_status, job_status = _check_job_step_done(
        request_id, InstaceActions.INSTANCE_CLONE_DISK_SNAPSHOT_COMMIT)
    if ret_check_status and job_status is 1:
        message = "pass"
        # logging.info(message)
        return ActionStatus.SUCCSESS, message
    else:
        _add_instance_actions(
            uuid, request_id, user_id,
            InstaceActions.INSTANCE_CLONE_DISK_SNAPSHOT_COMMIT, 'start')
        src_instance_data = ins_s.InstanceService().get_instance_info(
            src_instance_id)
        src_instance_name = src_instance_data['name']
        src_instance_uuid = src_instance_data['uuid']
        _status = ActionStatus.SUCCSESS
        msg = "虚拟机 %s 整合磁盘快照成功" % src_instance_name
        # 整合快照文件
        # for disk_tag in disk_tag_list:
        #     flag = False
        #     i = 0
        #     while i < 3 and not flag:
        #         time.sleep(5)
        #         ret_snapshot_commit = ansibleCmd.disk_snapshot_commit(source_host,src_instance_name,disk_tag)
        #         if not ret_snapshot_commit:
        #             i += 1
        #             err_msg = 'vm %s commit snapshot file for %s fail' % (src_instance_name, disk_tag)
        #             logging.info(err_msg)
        #         else:
        #             flag = True
        #     if not flag:
        #         _status = ActionStatus.FAILD
        #         msg = '虚拟机 %s 磁盘快照 %s 文件整合失败' %(src_instance_name, disk_tag)
        #         break
        ret_commit, commmit_msg = vm_snapshot_commit(task_id, source_host,
                                                     src_instance_name,
                                                     disk_tag_list,
                                                     src_instance_uuid)
        if not ret_commit:
            _status = ActionStatus.FAILD
            msg = commmit_msg
        # if _status == ActionStatus.SUCCSESS:
        #     # 删除快照残余文件
        #     src_instance_uuid = src_instance_data['uuid']
        #     dest_dir = '/app/image/' + src_instance_uuid
        #     ret = rm_snapfile(source_host, dest_dir)
        #     if not ret:
        #         _status = False
        #         msg = "清除虚拟机%s快照残余文件失败" % src_instance_name
        _update_instance_actions(
            uuid, request_id, user_id,
            InstaceActions.INSTANCE_CLONE_DISK_SNAPSHOT_COMMIT, _status, msg)
        return _status, msg
Ejemplo n.º 7
0
def backup_instance_status(instance_id):
    '''
    这个函数作用是当热迁移失败时,由于前端VM页面并没有热迁移失败的状态码,所以在迁移过程中失败后,都直接将VM状态改为运行中
    :return:
    '''
    update_data = {
        'status': VMStatus.STARTUP,
        'updated_at': get_datetime_str()
    }
    where_data = {'id': instance_id}
    return ins_s.InstanceService().update_instance_info(
        update_data, where_data)
Ejemplo n.º 8
0
def instance_clone(instance_id):
    '''
        虚机克隆
    :param instance_id:
    :return:
    '''
    instance_newname = request.values.get('instance_newname')
    if not instance_id:
        logging.info('no instance_id when clone instance')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

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

    ins_status = ins_data['status']
    if ins_status != VMStatus.SHUTDOWN:
        logging.error('instance %s status %s is invalid when clone instance',
                      instance_id, ins_status)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='只能在关机状态下克隆虚机')

    ins_group = ins_s.get_group_of_instance(instance_id)
    if not ins_group:
        logging.error(
            'instance %s group data is no exist in db when clone instance',
            instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    ins_flavor = ins_s.get_flavor_of_instance(instance_id)
    if not ins_flavor:
        logging.error(
            'instance %s flavor data is no exist in db when clone instance',
            instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 检查应用组配额
    ins_group_id = ins_group['group_id']
    is_quota_enough, quota_msg = check_group_quota(ins_group_id, ins_flavor, 1)
    if not is_quota_enough:
        logging.error('group %s is no enough quota when clone instance',
                      ins_group_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg=quota_msg)

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Ejemplo n.º 9
0
def instance_recreate():
    '''
        重新创建虚拟机
    :return:
    '''
    instance_id = request.values.get('instance_id')
    if not instance_id:
        logging.info('no instance_id when recreate instance')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)
    if not ins_data:
        logging.error('no instance %s info when recreate instance',
                      instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Ejemplo n.º 10
0
def instance_os_version_modify(instance_id):
    '''
        修改os版本为unknown的虚拟机
    :param instance_id:
    :json param :
    :return:
    '''
    req_json = request.data
    req_data = json_helper.loads(req_json)
    n_os_version = req_data["os_version"]

    if not instance_id or not str(n_os_version):
        logging.info(
            'no instance_id or os_version when modify instance os version')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)
    if not ins_data:
        logging.error(
            'instance %s info is no exist in db when modify instance os version',
            instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # VM创建来源
    create_source = ins_data['create_source']

    # 本平台
    if create_source == VMCreateSource.OPENSTACK or create_source == VMCreateSource.ESX:
        # v2v迁移的VM
        ins_v2v_data = v2v_i_i_s.v2vInstanceinfo(
        ).get_v2v_instance_info_by_instance_id(instance_id)
        if ins_v2v_data:
            if ins_v2v_data['os_version'] and ins_v2v_data[
                    'os_version'] == "unknown":
                # 更新v2v虚拟机os版本
                update_data = {'os_version': n_os_version}
                where_data = {'instance_id': instance_id}
                v2v_i_i_s.v2vInstanceinfo().update_v2v_status(
                    update_data, where_data)
    else:
        # todo: kvm2.0需要增加对平台自身创建虚拟机操作系统版本校验,unknown的可以修改
        pass

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                       msg="操作系统版本更新成功")
Ejemplo n.º 11
0
def win_vm_std(request_id):
    v2v_task = v2v_op.v2vTaskService().get_v2v_task_by_requestid(request_id)
    vmip = v2v_task['vm_ip']
    ostype = 'Windows'
    ip_data = ip_s.IPService().get_ip_by_ip_address(vmip)
    vmmask_int = int(ip_data['netmask'])
    vmmask = exchange_maskint(vmmask_int)
    vmgateway = ip_data['gateway_ip']
    vmname = v2v_task['vm_name']
    dns1 = ip_data['dns1']
    dns2 = ip_data['dns2']
    host_ip = v2v_task['dest_host']
    cloudarea = v2v_task['cloud_area']
    connect_instance = instanceManager.libvirt_get_connect(
        host_ip, conn_type='instance', vmname=vmname)
    inject_stauts, mesg = instanceManager.v2v_esx_win_inject(
        connect_instance, vmname, vmip, vmgateway, dns1, dns2, vmmask, ostype,
        cloudarea)
    if inject_stauts:
        message = "信息注入成功"
        threadlock = threading.Lock()
        threadlock.acquire()
        v2v_op.updata_v2v_message(request_id, message)
        in_a_s.update_instance_actions(request_id, esx_v2vActions.WINDOWS_STD,
                                       ActionStatus.SUCCSESS, message)
        v2v_op.update_v2v_step(request_id, esx_v2vActions.WINDOWS_STD)
        v2v_op.updata_v2v_ontask(request_id, '0')
        vm_uuid = v2v_op.v2vTaskService().get_v2v_task_by_requestid(
            request_id)['vm_uuid']
        v2v_op.update_v2v_actions(request_id, 1)
        v2v_op.update_v2v_step(request_id, esx_v2vActions.WINDOWS_STD)
        where_data = {'uuid': vm_uuid}
        update_data = {'status': '3'}
        ins_s.InstanceService().update_instance_info(update_data, where_data)
        threadlock.release()
    else:
        message = "信息注入失败"
        threadlock = threading.Lock()
        threadlock.acquire()
        v2v_op.updata_v2v_message(request_id, message)
        v2v_op.update_v2v_actions(request_id, ActionStatus.FAILD)
        v2v_op.updata_v2v_ontask(request_id, '0')
        in_a_s.update_instance_actions(request_id, esx_v2vActions.WINDOWS_STD,
                                       ActionStatus.FAILD, message)
        threadlock.release()
Ejemplo n.º 12
0
def _vm_create_disk_snapshot(images, uuid, user_id, request_id, source_host,
                             src_instance_id):
    ret_check_status, job_status = _check_job_step_done(
        request_id, InstaceActions.INSTANCE_CLONE_DISK_SNAPSHOT)
    if ret_check_status and job_status is 1:
        message = "pass"
        # logging.info(message)
        return ActionStatus.SUCCSESS, message
    else:
        _add_instance_actions(uuid, request_id, user_id,
                              InstaceActions.INSTANCE_CLONE_DISK_SNAPSHOT,
                              'start')
        src_instance_data = ins_s.InstanceService().get_instance_info(
            src_instance_id)
        src_instance_name = src_instance_data['name']
        src_instance_uuid = src_instance_data['uuid']
        connect_instance = vmManager.libvirt_get_connect(
            source_host, conn_type='instance', vmname=src_instance_name)
        if not connect_instance:
            _status = ActionStatus.FAILD
            msg = "源vm%s创建磁盘快照失败,libvirt连接失败" % src_instance_name
        else:
            #ret_disk_snapshot = ansibleCmd.create_disk_exter_snapshot(source_host,src_instance_name,snapshot_disk_data)
            snapshot_disk_data = []
            for image in images:
                image_url = '/app/image/' + src_instance_uuid + '/' + image
                snapshot_disk_data.append(image_url)
            ret_disk_snapshot = vmManager.ex_disk_snapshot(
                source_host, src_instance_name, snapshot_disk_data)
            if not ret_disk_snapshot:
                _status = ActionStatus.FAILD
                msg = "源vm %s 创建磁盘快照失败" % src_instance_name
            else:
                _status = ActionStatus.SUCCSESS
                msg = "源vm %s 创建磁盘快照成功" % src_instance_name

        _update_instance_actions(uuid, request_id, user_id,
                                 InstaceActions.INSTANCE_CLONE_DISK_SNAPSHOT,
                                 _status, msg)
        return _status, msg
Ejemplo n.º 13
0
def instance_reboot():
    '''
        虚机重启/强制重启
    :return:
    '''
    ins_ids = request.values.get('instance_ids')
    # 区分重启和强制重启
    flag = request.values.get('flag')
    if not ins_ids or not flag:
        logging.error('no instance_ids or flag when reboot instance')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_ids_list = ins_ids.split(',')
    # 操作的instance数
    all_num = len(ins_ids_list)
    fail_num = 0
    for _ins_id in ins_ids_list:
        _ins_data = ins_s.InstanceService().get_instance_info(_ins_id)
        if _ins_data:
            _ret_start = ins_a_s.reboot_instance(_ins_data)
            if not _ret_start:
                fail_num += 1
                continue
        else:
            logging.info(
                'the instance is not exist in db when reboot instance')
            fail_num += 1
            continue

    # 全失败
    if fail_num == all_num:
        logging.error("reboot instance all failed")
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("reboot instance part failed")
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分虚拟机重启成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Ejemplo n.º 14
0
def _get_source_vm_disks(src_instance_id, source_host):
    src_image_list = []
    src_instance_data = ins_s.InstanceService().get_instance_info(
        src_instance_id)
    src_instance_name = src_instance_data['name']
    get_device_status, vm_disks_info = vmManager.libvirt_get_instance_device(
        source_host, src_instance_name)
    if get_device_status == -100:
        _status = ActionStatus.FAILD
        msg = 'get source vm disk list fail'
        return _status, msg
    else:
        for disk in vm_disks_info:
            if disk['image'] is None:
                continue
            src_image_list.append(disk['image'])
        if src_image_list == []:
            msg = 'source vm disk list is empty'
            _status = ActionStatus.FAILD
            return _status, msg
        else:
            _status = ActionStatus.SUCCSESS
            return _status, src_image_list
Ejemplo n.º 15
0
def hot_migrate_init(instance_id):
    '''
        获取迁移时满足条件的目标主机
    :param instance_id:
    :return:
    '''

    # def _check_init():
    # 检测虚拟机本身是否符合迁移条件,暂时不做
    # pass

    def _check_cpu():
        #暂时不检测CPU型号
        pass

    def _check_mem(host, instance_mem):
        '''
            检测host是否有足够的内存资源和磁盘资源
        :param host:
        :param instance_mem:
        :return:
        '''
        # host已分配内存
        assign_mem = host_s.get_vm_assign_mem_of_host(host['host_id'])
        # 已分配 + 预分配 > 总大小
        if assign_mem + int(instance_mem) >= int(host['mem_size']):
            logging.error(
                'host %s assign mem %s + instance mem %s > mem size %s',
                host['host_id'], assign_mem, instance_mem, host['mem_size'])
            return False
        return True

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

    resp = MigrateHostsResp()

    ins_data = ins_s.InstanceService().get_instance_info(instance_id)
    if ins_data:
        resp.instance_name = ins_data['name']
        resp.instance_status = ins_data['status']

    ins_flavor_data = ins_s.get_flavor_of_instance(instance_id)
    if ins_flavor_data:
        resp.instance_cpu = ins_flavor_data['vcpu']
        resp.instance_mem = ins_flavor_data['memory_mb']
        resp.instance_disk = ins_flavor_data['root_disk_gb']

    ins_ip_data = ins_s.get_ip_of_instance(instance_id)
    if ins_ip_data:
        resp.instance_ip = ins_ip_data['ip_address']

    ins_host = ins_s.get_host_of_instance(instance_id)
    if not ins_host:
        logging.error(
            'instance %s of host is not exist in db when get migrate host',
            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(ins_host['hostpool_id'])
    if all_hosts_nums <= 0:
        logging.error('no host in hostpool %s when get migrate host',
                      ins_host['hostpool_id'])
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                           data={},
                                           msg="集群下没有一台可用物理机")

    # 过滤host
    # 这里不核对host的cpu型号
    hosts_after_filter = host_s_s.migrate_filter_hosts(all_hosts_data,
                                                       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.SUCCESS,
                                           data={},
                                           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.SUCCESS,
            data={},
            msg="集群内其他物理机cpu、内存资源不足或者应用互斥,暂时不能迁移")

    ins_flavor = ins_s.get_flavor_of_instance(instance_id)
    if not ins_flavor:
        logging.error(
            'instance %s flavor is not exist in db when get migrate host',
            instance_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="kvm平台未找到指定配置规格")

    for _host in host_after_match:
        # 去除本身host / 内存/磁盘分配足够
        if _host['host_id'] != ins_host['id']:
            _h = {
                'host_id':
                _host['host_id'],
                'host_name':
                _host['name'],
                'current_cpu_used':
                _host['current_cpu_used'],
                'current_mem_used':
                _host['current_mem_used'],
                'free_disk_space':
                int(_host["disk_size"]) *
                (100 - int(_host["current_disk_used"])) / 100
            }
            resp.host_list.append(_h)

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                       data=resp.to_json())
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
        def insert_log(*argv, **kwargs):
            user = user_service.get_user()
            res = func(*argv, **kwargs)
            instance_data = ""
            try:
                tmp = json.loads(res.data)
                # 根据不同action拼接extra_data
                if request.values.get('instance_ids'):  # 删除VM、开机、关机
                    try:
                        # instance_ids = json.dumps(request.values.get('instance_ids'))
                        ins_ids = request.values.get('instance_ids')
                        ins_ids_list = ins_ids.split(',')
                        for _ins_id in ins_ids_list:
                            _ins_data = ins_s.InstanceService(
                            ).get_instance_info(_ins_id)
                            instance_data += "name:" + _ins_data[
                                'name'] + "," + "uuid:" + _ins_data[
                                    'uuid'] + "; "
                    except:
                        pass

                elif operation_action == OperationAction.ADD:  # 创建VM
                    try:
                        hostpool_id = json.dumps(kwargs['hostpool_id'])
                        image_name = request.values.get('image_name')
                        flavor_id = request.values.get('flavor_id')
                        count = request.values.get('count')
                        app_info = request.values.get('app_info')
                        group_id = request.values.get('group_id')
                        owner = request.values.get('owner')
                        instance_data += "hostpool_id:" + hostpool_id + "," + "image_name:" + image_name + "," \
                                         + "flavor_id:" + flavor_id + "," + "count:" + count + "," \
                                         + "app_info:" + app_info + "," + "group_id:" + group_id + "," \
                                         + "owner:" + owner + ";"
                    except:
                        pass

                elif operation_action == OperationAction.MIGRATE or operation_action == OperationAction.HOT_MIGRATE:  # 冷迁移、热迁移
                    try:
                        _ins_id = json.dumps(kwargs['instance_id'])
                        _host_id = json.dumps(kwargs['host_id'])
                        host_data_d = host_s.HostService().get_host_info(
                            _host_id)
                        # host_data_s = ins_s.get_host_of_instance(_ins_id)  # str(host_data_s['name'])
                        _ins_data = ins_s.InstanceService().get_instance_info(
                            _ins_id)
                        # TODO: add src_host
                        instance_data += "name:" + _ins_data['name'] + "," + "uuid:" + _ins_data['uuid'] + "," \
                                         + "src_host:" + "," + "dst_host:" + str(host_data_d['name']) + ";"
                    except:
                        pass

                elif operation_action == OperationAction.CLONE_CREATE:  # 克隆创建
                    try:
                        _ins_id = request.values.get('instance_id')
                        _ins_data = ins_s.InstanceService().get_instance_info(
                            _ins_id)
                        instance_data += "name:" + _ins_data[
                            'name'] + "," + "uuid:" + _ins_data['uuid'] + "; "
                    except:
                        pass

                elif operation_action == OperationAction.ALTER:  # 修改VM配置
                    try:
                        _flavor_id = request.values.get('flavor_id')
                        # _disk_gb_list_req = request.values.get('disk_gb_list')
                        _app_info = request.values.get('app_info')
                        _owner = request.values.get('owner')
                        _group_id = request.values.get('group_id')
                        _net_conf_list_req = request.values.get(
                            'net_status_list')
                        # _ins_id = request.values.get('instance_id')
                        _ins_id = json.dumps(kwargs['instance_id'])
                        _extend_list_req = request.values.get('extend_list')
                        # _qemu_ga_update_req = request.values.get('qemu_ga_update')
                        _ins_data = ins_s.InstanceService().get_instance_info(
                            _ins_id)
                        instance_data += "name:" + _ins_data['name'] + "," + "uuid:" + _ins_data['uuid'] + "," \
                                         + "owner:" + _owner + "," + "group_id:" + _group_id + "," \
                                         + "flavor_id:" + _flavor_id + "," + "app_info:" + _app_info + "," \
                                         + "extend_list:" + _extend_list_req + "," \
                                         + "net_conf_list_req:" + _net_conf_list_req + ";"
                    except:
                        pass

                elif kwargs:  # 克隆备份
                    try:
                        _ins_id = json.dumps(kwargs['instance_id'])
                        _ins_data = ins_s.InstanceService().get_instance_info(
                            _ins_id)
                        instance_data += "name:" + _ins_data[
                            'name'] + "," + "uuid:" + _ins_data['uuid'] + "; "
                    except:
                        pass
                else:
                    pass
            except:
                return res

            if tmp["code"] == ErrorCode.SUCCESS:
                operation_result = "SUCCESS"
            elif tmp["code"] == ErrorCode.SUCCESS_PART:
                operation_result = "SUCCESS_PART"
            else:
                operation_result = "FAILED"
                try:
                    instance_data += " ErrorMsg:" + tmp["msg"]
                except:
                    pass

            client_ip = request.headers.get('X-Forwarded-For', '')
            insert_data = {
                "operator": user["user_id"],
                "operator_ip": client_ip,
                "operation_object": operation_object,
                "operation_action": operation_action,
                "operation_date": time_helper.get_datetime_str(),
                "operation_result": operation_result,
                "extra_data": "" + instance_data
            }
            OperationService().insert_operation(insert_data)
            return res
Ejemplo n.º 19
0
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'
Ejemplo n.º 20
0
def get_collect_request_multithreading(task_idapi, task_idkvm, vm_count,
                                       request_opr_user, request_api_origin):
    # 判断此工单是否有线程在追踪
    try:
        params = {
            'WHERE_AND': {
                '=': {
                    'taskid_kvm': task_idkvm,
                    'taskid_api': task_idapi,
                    'istraceing': '1'
                },
            }
        }
        ret_traceing_nums, ret_traceing_data = request_r_s.RequestRecordService(
        ).request_db_query_data(**params)
        if ret_traceing_nums > 0:
            return

        # 标记工单为跟踪中
        _update_data = {
            'istraceing': '1',
        }
        _where_data = {
            'taskid_kvm': task_idkvm,
        }
        ret = request_r_s.RequestRecordService().update_request_status(
            _update_data, _where_data)
        if ret <= 0:
            logging.error('update request %s status to db failed' % task_idkvm)

        ret_request_re = request_r_s.RequestRecordService(
        ).get_request_record_info_by_taskid_kvm(task_idkvm)
        request_ip = ret_request_re["request_ip"]

        succeed_http_code = ['200', '500']
        instance_actions_succeed_params = {
            'WHERE_AND': {
                '=': {
                    'task_id': task_idkvm,
                    'action': 'instance_inject_data',
                    'status': 1
                },
            },
        }
        # instance_actions_failed_params = {
        #     'WHERE_AND': {
        #         '=': {
        #             'task_id': task_idkvm,
        #             'status': 2
        #         },
        #         '!=': {
        #             'action': 'image_sync_status'
        #         },
        #     },
        # }
        instance_timeout_failed_params = {
            'WHERE_AND': {
                '=': {
                    'task_id': task_idkvm,
                    'status': VMStatus.CREATE_ERROR
                },
            },
        }
        vm_succeed_count_db_ret, vm_succeed_data = instance_a_s.InstanceActionsServices(
        ).query_data(**instance_actions_succeed_params)
        # vm_failed_count_db_ret, vm_failed_data =
        # instance_a_s.InstanceActionsServices().query_data(**instance_actions_failed_params)
        vm_createtimeout_count_db_ret, vm_createtimeout_failed_data = instance_s.InstanceService(
        ).query_data(**instance_timeout_failed_params)
        if not vm_succeed_count_db_ret:
            vm_succeed_count_db_ret = 0

        if not vm_createtimeout_count_db_ret:
            vm_createtimeout_count_db_ret = 0

        instances_uuid = []
        if vm_succeed_count_db_ret > 0:
            for per_request_data in vm_succeed_data:
                instances_uuid.append(per_request_data['instance_uuid'])

            if vm_count == vm_succeed_count_db_ret:
                # 通过虚拟机uuid查询主机名、ip、物理机序列号
                vm_datas = []
                for instance_uuid in instances_uuid:
                    ret_ins = instance_s.InstanceService(
                    ).get_instance_info_by_uuid(instance_uuid)
                    if ret_ins:
                        ret_ins_host = instance_s.get_host_of_instance(
                            ret_ins['id'])
                        ret_ins_ip = instance_s.get_net_segment_info_of_instance(
                            ret_ins['id'])
                        if ret_ins_host and ret_ins_ip:
                            vm_data = {
                                'instance_ids': ret_ins['id'],
                                'host_name': ret_ins['name'],
                                'ip': ret_ins_ip['ip_address'],
                                'ip_type': ret_ins_ip['segment_type'],
                                'sn': ret_ins_host['sn'],
                                'UUID': instance_uuid,
                                'net_name': ret_ins_ip['segment'],
                                'subnet_mask': ret_ins_ip['netmask'],
                                'gateway': ret_ins_ip['gateway_ip'],
                                'vlan_id': ret_ins_ip['vlan'],
                                'passWord': decrypt(ret_ins['password'])
                            }
                            vm_datas.append(vm_data)

                msg_detail = {'opUser': request_opr_user, 'vm': vm_datas}
                # 回调外部接口
                response_to_api_status = '1'
                if request_api_origin == ApiOrigin.VISHNU:
                    ret_code = msg_to_vishnu(task_idapi, VsJobStatus.SUCCEED,
                                             msg_detail, request_ip)
                elif request_api_origin == ApiOrigin.SFSLB:
                    ret_code = msg_to_sfslb(task_idapi, VsJobStatus.SUCCEED,
                                            msg_detail, request_ip)
                elif request_api_origin == ApiOrigin.FWAF:
                    ret_code = msg_to_fwaf(task_idapi, VsJobStatus.SUCCEED,
                                           msg_detail, request_ip)
                else:
                    ret_code = msg_to_vishnu(task_idapi, VsJobStatus.SUCCEED,
                                             msg_detail, request_ip)
                if ret_code not in succeed_http_code:
                    response_to_api_status = '0'
                update_db_time = get_datetime_str()
                _update_data = {
                    'task_status': '1',
                    'response_to_api': response_to_api_status,
                    'finish_time': update_db_time,
                    'request_status_collect_time': update_db_time,
                }
                _where_data = {
                    'taskid_kvm': task_idkvm,
                }
                ret = request_r_s.RequestRecordService().update_request_status(
                    _update_data, _where_data)
                if ret <= 0:
                    logging.error('update request %s status to db failed' %
                                  task_idkvm)
            elif (vm_createtimeout_count_db_ret + vm_succeed_count_db_ret) == vm_count \
                    and vm_createtimeout_count_db_ret > vm_count * 0.2:
                # 回调外部接口
                response_to_api_status = '1'

                if request_api_origin == ApiOrigin.VISHNU:
                    ret_code = msg_to_vishnu(task_idapi, VsJobStatus.FAILED,
                                             'all kvm instance create failed',
                                             request_ip)
                elif request_api_origin == ApiOrigin.SFSLB:
                    ret_code = msg_to_sfslb(task_idapi, VsJobStatus.FAILED,
                                            'all kvm instance create failed',
                                            request_ip)
                elif request_api_origin == ApiOrigin.FWAF:
                    ret_code = msg_to_fwaf(task_idapi, VsJobStatus.FAILED,
                                           'all kvm instance create failed',
                                           request_ip)
                else:
                    ret_code = msg_to_vishnu(task_idapi, VsJobStatus.FAILED,
                                             'all kvm instance create failed',
                                             request_ip)

                if ret_code not in succeed_http_code:
                    response_to_api_status = '0'
                update_db_time = get_datetime_str()
                _update_data = {
                    'task_status': '2',
                    'response_to_api': response_to_api_status,
                    'finish_time': update_db_time,
                    'request_status_collect_time': update_db_time,
                }
                _where_data = {
                    'taskid_kvm': task_idkvm,
                }
                ret = request_r_s.RequestRecordService().update_request_status(
                    _update_data, _where_data)
                if ret <= 0:
                    logging.error('update request %s status to db failed' %
                                  task_idkvm)
            else:
                if (vm_createtimeout_count_db_ret +
                        vm_succeed_count_db_ret) == vm_count:
                    # 把成功创建的虚拟机返回外部接口
                    """
                    vm_datas = []
                    for instance_uuid in instances_uuid:
                        ret_ins = instance_s.InstanceService().get_instance_info_by_uuid(instance_uuid)
                        if ret_ins:
                            ret_ins_host = instance_s.get_host_of_instance(ret_ins['id'])
                            ret_ins_ip = instance_s.get_net_segment_info_of_instance(ret_ins['id'])
                            if ret_ins_host and ret_ins_ip:
                                vm_data = {
                                    'host_name': ret_ins['name'],
                                    'ip': ret_ins_ip['ip_address'],
                                    'sn': ret_ins_host['sn'],
                                    'UUID': instance_uuid,
                                    'net_name': ret_ins_ip['segment'],
                                    'subnet_mask': ret_ins_ip['netmask'],
                                    'gateway': ret_ins_ip['gateway_ip'],
                                    'vlan_id': ret_ins_ip['vlan']
                                }
                                vm_datas.append(vm_data)

                    msg_detail = {'opUser': request_opr_user, 'vm': vm_datas}
                    """
                    # 回调外部接口
                    response_to_api_status = '1'
                    if request_api_origin == ApiOrigin.VISHNU:
                        ret_code = msg_to_vishnu(
                            task_idapi, VsJobStatus.FAILED,
                            'part of kvm instance create failed', request_ip)
                    elif request_api_origin == ApiOrigin.SFSLB:
                        ret_code = msg_to_sfslb(
                            task_idapi, VsJobStatus.FAILED,
                            'part of kvm instance create failed', request_ip)
                    elif request_api_origin == ApiOrigin.FWAF:
                        ret_code = msg_to_fwaf(
                            task_idapi, VsJobStatus.FAILED,
                            'part of kvm instance create failed', request_ip)
                    else:
                        ret_code = msg_to_vishnu(
                            task_idapi, VsJobStatus.FAILED,
                            'part of kvm instance create failed', request_ip)

                    if ret_code not in succeed_http_code:
                        response_to_api_status = '0'

                    update_db_time = get_datetime_str()
                    _update_data = {
                        'task_status': '2',
                        'response_to_api': response_to_api_status,
                        'finish_time': update_db_time,
                        'request_status_collect_time': update_db_time,
                    }
                    _where_data = {
                        'taskid_kvm': task_idkvm,
                    }
                    ret = request_r_s.RequestRecordService(
                    ).update_request_status(_update_data, _where_data)
                    if ret <= 0:
                        logging.error('update request %s status to db failed' %
                                      task_idkvm)
                else:
                    # 成功失败的总数量未等于count
                    pass

        elif vm_createtimeout_count_db_ret > 0:
            # 全部虚拟机创建失败
            if (vm_createtimeout_count_db_ret + vm_succeed_count_db_ret) == vm_count \
                    and vm_createtimeout_count_db_ret > vm_count * 0.2:
                # 回调外部接口
                response_to_api_status = '1'
                if request_api_origin == ApiOrigin.VISHNU:
                    ret_code = msg_to_vishnu(task_idapi, VsJobStatus.FAILED,
                                             'all kvm instance create failed',
                                             request_ip)
                elif request_api_origin == ApiOrigin.SFSLB:
                    ret_code = msg_to_sfslb(task_idapi, VsJobStatus.FAILED,
                                            'all kvm instance create failed',
                                            request_ip)
                elif request_api_origin == ApiOrigin.FWAF:
                    ret_code = msg_to_fwaf(task_idapi, VsJobStatus.FAILED,
                                           'all kvm instance create failed',
                                           request_ip)
                else:
                    ret_code = msg_to_vishnu(task_idapi, VsJobStatus.FAILED,
                                             'all kvm instance create failed',
                                             request_ip)

                if ret_code not in succeed_http_code:
                    response_to_api_status = '0'
                update_db_time = get_datetime_str()
                _update_data = {
                    'task_status': '2',
                    'response_to_api': response_to_api_status,
                    'finish_time': update_db_time,
                    'request_status_collect_time': update_db_time,
                }
                _where_data = {
                    'taskid_kvm': task_idkvm,
                }
                ret = request_r_s.RequestRecordService().update_request_status(
                    _update_data, _where_data)
                if ret <= 0:
                    logging.error('update request %s status to db failed' %
                                  task_idkvm)
        else:
            update_db_time = get_datetime_str()
            _update_data = {'request_status_collect_time': update_db_time}
            _where_data = {
                'taskid_kvm': task_idkvm,
            }
            ret = request_r_s.RequestRecordService().update_request_status(
                _update_data, _where_data)
            if ret <= 0:
                logging.error('update request %s status to db failed' %
                              task_idkvm)

        # 标记工单为完成追踪
        _update_data = {
            'istraceing': '0',
        }
        _where_data = {
            'taskid_kvm': task_idkvm,
        }
        ret = request_r_s.RequestRecordService().update_request_status(
            _update_data, _where_data)
        if ret <= 0:
            logging.error(
                'update request %s status to db failed when mark istraceing 1'
                % task_idkvm)

        return
    except Exception as e:
        logging.error('request {} threading exception error: {}'.format(
            task_idkvm, e))
        return
Ejemplo n.º 21
0
def _instance_db_info(uuid, vmname, vm_app_info, owner, flavor_id, group_id,
                      host, mac, vmdisk, ip_id, vmostype, requestid, ver_data):
    vm_ostype_todb = ''
    vmhost = ho_s.HostService().get_host_info_by_hostip(host)
    # 往instance表添加记录
    instance_data = {
        'uuid': uuid,
        'name': vmname,
        'displayname': vmname,
        'description': '',
        'status': VMStatus.CONVERTING,
        'typestatus': VMTypeStatus.NORMAL,
        'isdeleted': '0',
        'app_info': vm_app_info,
        'owner': owner,
        'created_at': get_datetime_str(),
        'create_source': VMCreateSource.ESX
    }
    ret = ins_s.InstanceService().add_instance_info(instance_data)
    if ret.get('row_num') <= 0:
        message = 'add instance info error when create instance'
        logging.info(
            'add instance info error when create instance, insert_data: %s',
            instance_data)
        return False, message

    instance_id = ret.get('last_id')

    if vmostype == 'Windows':
        vm_ostype_todb = 'windows'
    elif vmostype == 'Linux':
        vm_ostype_todb = 'linux'

    # 往v2v_instance_info表添加记录
    v2v_instance_data = {
        'instance_id': instance_id,
        'os_type': vm_ostype_todb,
        'isdeleted': '0',
        'created_at': get_datetime_str(),
        'request_id': requestid,
        'os_version': ver_data
    }
    ret_v2v_instance = v2v_in_i.v2vInstanceinfo().add_v2v_instance_info(
        v2v_instance_data)
    if ret_v2v_instance.get('row_num') <= 0:
        logging.info(
            'add v2v_instance info error when create instance, v2v_instance_data: %s',
            v2v_instance_data)
        message = 'add v2v_instance info error when create instance'
        return False, message

    # 往instance_flavor表添加记录
    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.info(
            'add instance_flavor info error when create instance, insert_data: %s',
            instance_flavor_data)
        message = 'add instance_flavor info error when create instance'
        return False, message

    # 往instance_group表添加记录
    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.info(
            'add instance_group info error when create instance, insert_data: %s',
            instance_group_data)
        message = 'add instance_group info error when create instance'
        return False, message

    # 往instance_host表添加记录
    instance_host_data = {
        'instance_id': instance_id,
        'instance_name': vmname,
        'host_id': vmhost['id'],
        'host_name': vmhost['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.info(
            'add instance_host info error when create instance, insert_data: %s',
            instance_host_data)
        message = 'add instance_host info error when create instance'
        return False, message

    # 往instance_ip表添加记录
    instance_ip_data = {
        'instance_id': instance_id,
        'ip_id': ip_id,
        'mac': mac,
        'type': InstanceNicType.MAIN_NETWORK_NIC,
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret4 = ins_ip_s.InstanceIPService().add_instance_ip_info(instance_ip_data)
    if ret4.get('row_num') <= 0:
        logging.info(
            'add instance_ip info error when create instance, insert_data: %s',
            instance_ip_data)
        message = 'add instance_ip info error when create instance'
        return False, message

    # 往instance_disk表添加记录
    instance_disk_data = {
        'instance_id': instance_id,
        'size_gb': vmdisk,
        'mount_point': '',
        'dev_name': '',
        'isdeleted': '0',
        'created_at': get_datetime_str()
    }
    ret5 = ins_d_s.InstanceDiskService().add_instance_disk_info(
        instance_disk_data)
    if ret5.get('row_num') <= 0:
        logging.info(
            'add instance_disk info error when create instance, insert_data: %s',
            instance_disk_data)
        message = 'add instance_disk info error when create instance'
        return False, message
    message = "信息入库完成"
    return True, message
Ejemplo n.º 22
0
def v2v_openstack_del():

    #获取入参信息
    delete = request.values.get('delete')
    request_his = request.values.get('request_id')
    source = v2v_op.v2vTaskService().get_v2v_task_by_requestid(
        request_his)['source']

    if not source:
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg='v2v来源缺失')

    if delete != '1':
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg='参数错误')

    #判断当前任务是否完成
    data, message = v2v_op.get_v2v_deleteable(request_his)
    if data != '2':
        return_msg = message
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg=return_msg)
    else:
        if source == VMCreateSource.OPENSTACK:
            del_res, del_msg = del_action(request_his)
            if del_res == False:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg=del_msg)
        else:
            tag, errmsg = esx_del_action(request_his)
            if not tag:
                return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                   msg=errmsg)

        v2v_task = v2v_op.v2vTaskService().get_v2v_task_by_requestid(
            request_his)
        v2v_vm_uuid = v2v_task['vm_uuid']
        #更新instance表
        instance_info = ins_s.InstanceService().get_instance_info_by_uuid(
            v2v_vm_uuid)
        instance_id = instance_info['id']
        update_data = {'isdeleted': '1', 'deleted_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('删除instance %s 错误', instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='删除instance错误')

        # instance_flavor
        ret_f = ins_f_s.InstanceFlavorService().delete_instance_flavor(
            instance_id)
        if ret_f != 1:
            logging.error('delete instance %s flavor error', instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='删除instance flavor错误')

        # instance_group
        ret_g = ins_g_s.InstanceGroupService().delete_instance_group_info(
            instance_id)
        if ret_g != 1:
            logging.error('delete instance %s group error', instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='删除instance group错误')

        # instance_host
        update_data_h = {'isdeleted': '1', 'deleted_at': get_datetime_str()}
        where_data_h = {'instance_id': instance_id}
        ret_h = ins_h_s.InstanceHostService().update_instance_host_info(
            update_data_h, where_data_h)
        if ret_h != 1:
            logging.error('delete instance %s host error', instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='删除instance host错误')

        # instance_disk
        update_data_d = {'isdeleted': '1', 'deleted_at': get_datetime_str()}
        where_data_d = {'instance_id': instance_id}
        ret_d = ins_d_s.InstanceDiskService().update_instance_disk_info(
            update_data_d, where_data_d)
        if ret_d != 1:
            logging.error('delete instance %s disk error', instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='删除instance disk错误')

        # instance_ip
        update_data_ip = {'isdeleted': '1', 'deleted_at': get_datetime_str()}
        where_data_ip = {'instance_id': instance_id}
        ret_i_ip = ins_ip_s.InstanceIPService().update_instance_ip_info(
            update_data_ip, where_data_ip)
        if ret_i_ip != 1:
            logging.error('delete instance %s ip error', instance_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='删除instance ip错误')

        #更新v2v_instance_info
        update_data = {'isdeleted': '1', 'deleted_at': get_datetime_str()}
        where_data = {'instance_id': instance_id}
        ret_v2v_in_i = v2v_in_i.v2vInstanceinfo().update_v2v_status(
            update_data, where_data)
        if ret_v2v_in_i != 1:
            logging.error('delete v2v instance info error')
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='删除v2v instance info错误')

        # 删除vm的ip
        ip_data = ins_s.get_ip_of_instance(instance_id)
        ip_id = ip_data['id']
        if ip_data:
            ip_s.del_ip_info(ip_id)

        #更新v2v_task表
        where_v2v = {'request_id': request_his}
        update_v2v = {'destory': '1'}
        v2v_op.v2vTaskService().update_v2v_status(update_v2v, where_v2v)

        return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                           msg='删除v2v任务完成')
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'
Ejemplo n.º 24
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())
Ejemplo n.º 25
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)
Ejemplo n.º 26
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='修改配置成功')
Ejemplo n.º 27
0
def collect_instances_data(host_ip):
    '''
        收集指定主机下所有instance的信息
    :param host_ip:
    :return:
    '''
    print '*' * 40
    print 'start colletc host ' + host_ip + ' instance data at ' + get_datetime_str()

    libvirt_connect_instance = libvirt_get_connect(host=host_ip, conn_type='instances')
    # libvirt连接不上时需要将host下面所有虚拟机状态改为错误
    if not libvirt_connect_instance:
        logging.error('unable to connect host %s when collect data', host_ip)
        instances = ins_s.get_instances_by_host_ip(host_ip)
        for _ins in instances:
            _ins_data = ins_s.InstanceService().get_instance_info_by_uuid(_ins['uuid'])
            if not _ins_data:
                logging.warn('libvirt instance uuid %s , but not exist in db when collect data', _ins['uuid'])
                continue

            # 创建中虚拟机做判断,如果处于创建中大于45分钟,更新虚拟机状态为创建失败
            if _ins_data['status'] == VMStatus.CREATING:
                check_vm_create_status = _check_vm_creating_time(_ins_data['created_at'])
                if check_vm_create_status:
                    # 如果是克隆创建的vm则更新状态为克隆创建失败
                    if _ins_data['clone_source_host']:
                        _update_data_i = {
                            'status': VMStatus.CLONE_CREATE_ERROR,
                            'updated_at': get_datetime_str()
                        }
                        _where_data_i = {
                            'uuid': _ins['uuid']
                        }
                        ret_i_create = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
                        if ret_i_create != 1:
                            logging.error(
                                'update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                                _ins['uuid'], _update_data_i, _where_data_i)
                    else:
                        _update_data_i = {
                            'status': VMStatus.CREATE_ERROR,
                            'updated_at': get_datetime_str()
                        }
                        _where_data_i = {
                            'uuid': _ins['uuid']
                        }
                        ret_i_create = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
                        if ret_i_create != 1:
                            logging.error(
                                'update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                                _ins['uuid'], _update_data_i, _where_data_i)
                        continue

            # 虚拟机处于创建中状态小于45分钟、并且虚拟机状态被放到不更新状态列表中
            if _ins_data['status'] in INSTANCE_STATUS_NOT_UPDATE:
                logging.info('not update instance %s status when in status %s', _ins['uuid'], _ins_data['status'])
                continue

            # 如果是v2v机器、状态为转化中则不更新状态
            if _ins_data['status'] == VMStatus.CONVERTING:
                logging.info('not update instance %s status when in status %s', _ins['uuid'], _ins_data['status'])
                continue

            _update_data_i = {
                'status': VMStatus.ERROR,
                'updated_at': get_datetime_str()
            }
            _where_data_i = {
                'uuid': _ins['uuid']
            }
            ret_i = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
            if ret_i != 1:
                logging.error('update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                              _ins['uuid'], _update_data_i, _where_data_i)
    else:
        instances = libvirt_get_all_instances_by_host(libvirt_connect_instance, host_ip)
        for _ins in instances:
            _ins_data = ins_s.InstanceService().get_instance_info_by_uuid(_ins['uuid'])
            if not _ins_data:
                logging.warn('libvirt instance uuid %s , but not exist in db when collect data', _ins['uuid'])
                continue

            # 创建中虚拟机做判断,如果处于创建中大于45分钟,更新虚拟机状态为创建失败
            if _ins_data['status'] == VMStatus.CREATING:
                check_vm_create_status = _check_vm_creating_time(_ins_data['created_at'])
                if check_vm_create_status:
                    #如果是克隆创建的vm则更新状态为克隆创建失败
                    if _ins_data['clone_source_host']:
                        _update_data_i = {
                            'status': VMStatus.CLONE_CREATE_ERROR,
                            'updated_at': get_datetime_str()
                        }
                        _where_data_i = {
                            'uuid': _ins['uuid']
                        }
                        ret_i_create = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
                        if ret_i_create != 1:
                            logging.error(
                                'update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                                _ins['uuid'], _update_data_i, _where_data_i)
                    else:
                        _update_data_i = {
                            'status': VMStatus.CREATE_ERROR,
                            'updated_at': get_datetime_str()
                        }
                        _where_data_i = {
                            'uuid': _ins['uuid']
                        }
                        ret_i_create = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
                        if ret_i_create != 1:
                            logging.error(
                                'update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                                _ins['uuid'], _update_data_i, _where_data_i)
                        continue
                    continue

            # 虚拟机处于创建中状态小于45分钟、并且虚拟机状态被放到不更新状态列表中
            if _ins_data['status'] in INSTANCE_STATUS_NOT_UPDATE:
                logging.info('not update instance %s status when in status %s', _ins['uuid'], _ins_data['status'])
                continue

            # 虚拟机处于关机中,并且虚拟机真实状态为运行中,此时不做状态更新
            if _ins_data['status'] == VMStatus.SHUTDOWN_ING and _ins['status'] != VMLibvirtStatus.SHUTDOWN:
                continue

            _update_data_i = {
                'status': _libvirt_status_2_ins_status(_ins['status']),
                'updated_at': get_datetime_str()
            }
            _where_data_i = {
                'uuid': _ins['uuid']
            }
            ret_i = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
            if ret_i != 1:
                logging.error('update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                              _ins['uuid'], _update_data_i, _where_data_i)

        instances = ins_s.get_instances_by_host_ip(host_ip)
        for _ins in instances:
            _ins_data = ins_s.InstanceService().get_instance_info_by_uuid(_ins['uuid'])
            if not _ins_data:
                logging.warn('libvirt instance uuid %s , but not exist in db when collect data', _ins['uuid'])
                continue

            # 创建中虚拟机做判断,如果处于创建中大于45分钟,更新虚拟机状态为创建失败
            if _ins_data['status'] == VMStatus.CREATING:
                check_vm_create_status = _check_vm_creating_time(_ins_data['created_at'])
                if check_vm_create_status:
                    # 如果是克隆创建的vm则更新状态为克隆创建失败
                    if _ins_data['clone_source_host']:
                        _update_data_i = {
                            'status': VMStatus.CLONE_CREATE_ERROR,
                            'updated_at': get_datetime_str()
                        }
                        _where_data_i = {
                            'uuid': _ins['uuid']
                        }
                        ret_i_create = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
                        if ret_i_create != 1:
                            logging.error(
                                'update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                                _ins['uuid'], _update_data_i, _where_data_i)
                    else:
                        _update_data_i = {
                            'status': VMStatus.CREATE_ERROR,
                            'updated_at': get_datetime_str()
                        }
                        _where_data_i = {
                            'uuid': _ins['uuid']
                        }
                        ret_i_create = ins_s.InstanceService().update_instance_info(_update_data_i, _where_data_i)
                        if ret_i_create != 1:
                            logging.error(
                                'update instance %s data error when collect instance data, update_data:%s, where_data:%s',
                                _ins['uuid'], _update_data_i, _where_data_i)

    # 更新收集时间
    _update_data_h = {
        'instances_collect_time': get_datetime_str()
    }
    _where_data_h = {
        'ipaddress': host_ip,
        'isdeleted': '0'
    }
    ret_h = host_s.HostService().update_host_info(_update_data_h, _where_data_h)
    if ret_h != 1:
        logging.error('update collect time error when collect instance data, update_data:%s, where_data:%s',
                      _update_data_h, _where_data_h)

    print 'end colletc host ' + host_ip + ' instance data at ' + get_datetime_str()
    print '*' * 40
Ejemplo n.º 28
0
def instance_shutdown():
    '''
        虚机关机/强制关机
    :return:
    '''
    ins_ids = request.values.get('instance_ids')
    # 区分关机和强制关机
    flag = request.values.get('flag')
    if not ins_ids or not flag:
        logging.info('no instance_ids or flag when shutdown instance')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_ids_list = ins_ids.split(',')
    # 操作的instance数
    all_num = len(ins_ids_list)
    if all_num > int(INSTANCE_MAX_SHUTDOWN):
        logging.info('shutdown nums %s is greater than max %s', all_num,
                     INSTANCE_MAX_SHUTDOWN)
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    msg = None
    fail_num = 0
    for _ins_id in ins_ids_list:
        _ins_data = ins_s.InstanceService().get_instance_info(_ins_id)
        if _ins_data:
            # 本身是关机状态的不能再关机
            # if _ins_data['status'] == VMStatus.SHUTDOWN or _ins_data['status'] == VMStatus.SHUTDOWN_ING:
            #     logging.info('the instance status %s is invalid when shutdown instance', _ins_data['status'])
            #     fail_num += 1
            #     # 单台操作且已失败则直接跳出循环
            #     if all_num == 1:
            #         msg = '该虚拟机已经关机,请勿重复关机'
            #         break
            #     continue
            # else:
            #     _ret_shut, _ret_msg = ins_a_s.shutdown_instance(_ins_data, int(flag))
            #     if not _ret_shut:
            #         fail_num += 1
            #         # 单台操作且已失败则直接跳出循环
            #         if all_num == 1:
            #             msg = _ret_msg
            #             break
            #         continue

            if _ins_data['status'] == VMStatus.SHUTDOWN:
                logging.info(
                    'the instance status %s is invalid when shutdown instance',
                    _ins_data['status'])
                fail_num += 1
                # 单台操作且已失败则直接跳出循环
                if all_num == 1:
                    msg = '该虚拟机已经关机,请勿重复关机'
                    break
                continue
            elif _ins_data['status'] == VMStatus.SHUTDOWN_ING and int(
                    flag) == 1:
                logging.info(
                    'the instance status %s is invalid when shutdown instance',
                    _ins_data['status'])
                fail_num += 1
                # 单台操作且已失败则直接跳出循环
                if all_num == 1:
                    msg = '该虚拟机正在关机中,请勿重复关机'
                    break
                continue
            else:
                _ret_shut, _ret_msg = ins_a_s.shutdown_instance(
                    _ins_data, int(flag))
                if not _ret_shut:
                    fail_num += 1
                    # 单台操作且已失败则直接跳出循环
                    if all_num == 1:
                        msg = _ret_msg
                        break
                    continue
        else:
            logging.info(
                'the instance is not exist in db when shutdown instance')
            fail_num += 1
            continue

    # 全失败
    if fail_num == all_num:
        logging.error("shutdown instance all failed")
        if msg:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=msg)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("shutdown instance part failed")
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分虚拟机关机成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
Ejemplo n.º 29
0
def instance_detail(instance_id):
    '''
        获取虚机详情
    :param instance_id:
    :return:
    '''
    if not instance_id:
        logging.info('no instance_id when get instance detail')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

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

    # VM创建来源
    create_source = ins_data['create_source']

    ins_flavor = ins_s.get_flavor_of_instance(instance_id)
    if not ins_flavor:
        logging.error(
            'instance %s flavor info is no exist in db when get instance detail',
            instance_id)
        cpu = None
        memory_mb = None
        root_disk_gb = None
    else:
        cpu = ins_flavor['vcpu']
        memory_mb = ins_flavor['memory_mb']
        root_disk_gb = ins_flavor['root_disk_gb']

    system = None
    sys_version = None
    image_name = None
    # 本平台
    if create_source == VMCreateSource.CLOUD_SOURCE:
        ins_images = ins_s.get_images_of_instance(instance_id)
        if not ins_images:
            logging.error(
                'instance %s image info is no exist in db when get instance detail',
                instance_id)
        else:
            system = ins_images[0]['system']
            sys_version = ins_images[0]['version']
            image_name = ins_images[0]['displayname']
    elif create_source == VMCreateSource.OPENSTACK or create_source == VMCreateSource.ESX:
        # v2v迁移的VM
        ins_v2v_data = v2v_i_i_s.v2vInstanceinfo(
        ).get_v2v_instance_info_by_instance_id(instance_id)
        if ins_v2v_data:
            system = ins_v2v_data['os_type']
            sys_version = ins_v2v_data['os_version']

    ins_group = ins_s.get_group_of_instance(instance_id)
    if not ins_group:
        logging.error(
            'instance %s group info is no exist in db when get instance detail',
            instance_id)
        group_name = None
    else:
        group_name = ins_group['name']

    ins_ip = ins_s.get_ip_of_instance(instance_id)
    if not ins_ip:
        logging.error(
            'instance %s ip info is no exist in db when get instance detail',
            instance_id)
        ip_address = None
    else:
        ip_address = ins_ip['ip_address']

    ins_netarea = ins_s.get_netarea_of_instance(instance_id)
    if not ins_netarea:
        logging.error(
            'instance %s net area info is no exist in db when get instance detail',
            instance_id)
        net_area = None
    else:
        net_area = ins_netarea['name']

    ins_disks = ins_s.get_disks_of_instance(instance_id)
    if not ins_disks:
        logging.error(
            'instance %s disks info is no exist in db when get instance detail',
            instance_id)
        disk_gb = None
    else:
        # disk_gb = ins_disks[0]['size_gb']
        disk_gb = sum([int(i['size_gb']) for i in ins_disks])

    ins_datacenter = ins_s.get_datacenter_of_instance(instance_id)
    if not ins_datacenter:
        logging.error(
            'instance %s datacenter info is no exist in db when get instance detail',
            instance_id)
        dc_type = None
    else:
        dc_type = ins_datacenter['dc_type']

    data = {
        'instance_name': ins_data['name'],
        'uuid': ins_data['uuid'],
        'ip_address': ip_address,
        'dc_type': dc_type,
        'net_area': net_area,
        'system': system,
        'sys_version': sys_version,
        'image_name': image_name,
        'cpu': cpu,
        'memory_mb': memory_mb,
        'root_disk_gb': root_disk_gb,
        'disk_gb': disk_gb,
        'app_info': ins_data['app_info'],
        'owner': ins_data['owner'],
        'group_name': group_name,
        'create_source': create_source
    }
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=data)
Ejemplo n.º 30
0
def instance_delete():
    '''
        虚机删除
        关机超过一天才能删除
    :return:
    '''
    request_from_vishnu = False
    if get_user()['user_id'] == 'vishnu':
        is_admin = True
        request_from_vishnu = True
    else:
        # 判断操作用户身份
        role_ids = current_user_role_ids()
        # 系统管理员
        if 1 in role_ids:
            is_admin = True
        else:
            is_admin = False

    permission_limited = False

    ins_ids = request.values.get('instance_ids')
    if not ins_ids:
        logging.info('no instance_ids when delete instance')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    ins_ids_list = ins_ids.split(',')
    # 操作的instance数
    all_num = len(ins_ids_list)
    if all_num > int(INSTANCE_MAX_DELETE):
        logging.info('delete nums %s is greater than max %s', all_num,
                     INSTANCE_MAX_DELETE)
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    fail_num = 0
    for _ins_id in ins_ids_list:
        # 查询虚拟机对应环境信息,应用管理员不能删除非DEV环境虚拟机
        ins_group = ins_s.get_group_of_instance(_ins_id)
        if not ins_group:
            logging.error(
                'instance %s group data is no exist in db when delete instance',
                str(_ins_id))
            fail_num += 1
            continue
        else:
            if not is_admin and int(
                    ins_group['dc_type']) != DataCenterType.DEV:
                permission_limited = True
                fail_num += 1
                continue
        _ins_data = ins_s.InstanceService().get_instance_info(_ins_id)
        if _ins_data:
            # 维石只能删除克隆备份的虚拟机
            if request_from_vishnu and 'clone' not in _ins_data['name']:
                fail_num += 1
                continue
            _ret_del = ins_a_s.delete_instance(_ins_data, _ins_data['status'])
            if not _ret_del:
                fail_num += 1
                continue
        else:
            logging.error(
                'the instance is not exist in db when delete instance')
            fail_num += 1
            continue

    # 全失败
    if fail_num == all_num:
        logging.error("delete instance all failed")
        if permission_limited:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg="非DEV环境虚拟机请联系系统组删除")
        elif request_from_vishnu:
            return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
        else:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    # 部分成功
    if 0 < fail_num < all_num:
        logging.error("delete instance part failed")
        if permission_limited:
            return json_helper.format_api_resp(
                code=ErrorCode.SUCCESS_PART,
                msg="部分虚拟机删除成功, 非DEV环境虚拟机请联系系统组删除")
        elif request_from_vishnu:
            return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
        else:
            return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                               msg="部分虚拟机删除成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)