예제 #1
0
def lock(host_id):
    '''
        锁定物理机,即虚机不分配到该物理机上
    :param host_id:
    :return:
    '''
    # flag:'1' 锁定  flag:'0' 解除锁定
    flag = request.values.get("flag")
    if not host_id or not flag:
        logging.info('no host_id or flag when lock/unlock host')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg="参数错误")

    host_data = host_service.HostService().get_host_info(host_id)
    if not (host_data and host_data['isdeleted'] == '0'):
        logging.info('the host %s is invalid when lock/unlock host', host_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    if host_data['typestatus'] == flag:
        logging.info('the host %s is done before when lock/unlock host',
                     host_id)
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS)

    update_data = {"typestatus": flag}
    where_data = {"id": host_id}
    ret = host_service.HostService().update_host_info(update_data, where_data)
    if ret != 1:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
예제 #2
0
def maintain(host_id):
    '''
        维护物理机
    :param host_id:
    :return:
    '''
    def _check_all_instance_shutdown(instance_list):
        '''
            检查是否所有VM都是关机状态
        :param instance_list:
        :return:
        '''
        shutdown_flag = True
        for _ins in instance_list:
            if _ins['status'] != VMStatus.SHUTDOWN:
                shutdown_flag = False
                break
        return shutdown_flag

    # flag:'2' 维护  flag:'0' 结束维护
    flag = request.values.get("flag")
    if not host_id or not flag:
        logging.info('no host_id or flag when maintain/unmaintain host')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg="参数错误")

    host_data = host_service.HostService().get_host_info(host_id)
    if not (host_data and host_data['isdeleted'] == '0'):
        logging.info('the host %s is invalid when maintain/unmaintain host',
                     host_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    if host_data['typestatus'] == flag:
        logging.info(
            'the host %s is done before when maintain/unmaintain host',
            host_id)
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS)

    # 需要该host没有vm,或者所有vm都关机时才能维护
    if flag == HostTypeStatus.MAINTAIN:
        vm_list = ins_s.get_instances_in_host(host_data['id'])
        if len(vm_list) > 0 and not _check_all_instance_shutdown(vm_list):
            logging.info(
                'no allow maintain host which has instances that no shutdown when maintain host'
            )
            return json_helper.format_api_resp(
                code=ErrorCode.SYS_ERR, msg="该HOST下存在着非关机状态的虚拟机,不能维护该HOST")

    update_data = {"typestatus": flag}
    where_data = {"id": host_id}
    ret = host_service.HostService().update_host_info(update_data, where_data)
    if ret != 1:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
예제 #3
0
def delete_host():
    ERR_RET = 0
    all_host_id = request.values.get("host_id")
    if not all_host_id:
        logging.info('no host_id input when delete host')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg="参数错误")
    for host_id in all_host_id.split(','):
        host_data = host_s.HostService().get_host_info(host_id)
        if not host_data:
            ERR_RET += 1
            continue

        if host_data['isdeleted'] == '1':
            ERR_RET += 1
            continue

        instance_nums = ins_s.get_instances_nums_in_host(host_id)
        if instance_nums == None:
            ERR_RET += 1
            continue
        elif instance_nums > 0:
            ERR_RET += 1
            continue
        elif instance_nums == 0:
            host_ip = host_data['ipaddress']
            host_s._pool_delete(host_ip)
            update_data = {
                "isdeleted": '1',
                "deleted_at": datetime.datetime.now()
            }
            where_data = {"id": host_id}
            db_ret = host_s.HostService().update_host_info(
                update_data, where_data)
            if db_ret != 1:
                ERR_RET += 1
                continue
            else:
                logging.info('host ' + str(host_id) + ' delete successful')
                continue

        else:
            ERR_RET += 1
            continue

    if ERR_RET == 0:
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
    elif len(all_host_id.split(',')) == 1 and ERR_RET == 1:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    elif len(all_host_id.split(',')) == ERR_RET:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)
    else:
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART)
예제 #4
0
def get_collect_hosts(interval=180, nums=20):
    '''
        获取前20个上次收集时间最久远并且超过了时间间隔的host
    :param interval:
    :param nums:
    :return:
    '''
    params = {
        'WHERE_AND': {
            '!=': {
                'isdeleted': '1',
                'status': '1'
            },
        },
        'ORDER': [
            ['host_collect_time', 'asc']
        ],
    }
    hosts_list = []
    hosts_nums, hosts_data = host_s.HostService().query_data(**params)
    for _host in hosts_data:
        if check_collect_time_out_interval(_host['host_collect_time'], interval) and len(hosts_list) <= nums:
            hosts_list.append(_host)

    return hosts_list
예제 #5
0
def collect_host_data(host_ip):
    result = connection_manager.host_is_up(CONN_TCP, host_ip)
    # host_status = connection_manager.host_is_up(CONN_SSH, host_ip)
    if result is True:
        status = HostStatus.RUNNING
        libvirtd_status = HostLibvirtdStatus.NORMAL
    elif result is "error(111, 'Connection refused')" or result is "timeout('timed out',)":
        status = HostStatus.ERROR
        libvirtd_status = HostLibvirtdStatus.UNUSUAL
    else:
        status = HostStatus.ERROR
        libvirtd_status = HostLibvirtdStatus.UNUSUAL

    # 更新收集时间
    _update_data_h = {
        'host_collect_time': get_datetime_str(),
        'status': status,
        'libvirtd_status': libvirtd_status
    }
    _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 host data, update_data:%s, where_data:%s',
                      _update_data_h, _where_data_h)

    print 'end colletc host ' + host_ip + ' data at ' + get_datetime_str()
    print '*' * 40
    return 0
예제 #6
0
def single_host_image_return(host_id):
    #获取当前host已有的镜像信息汇总
    res1, local_image_data = local_image_return(host_id)
    if not res1:
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg=local_image_data)
    else:
        #获取当前host上没有的镜像信息汇总
        res2, remote_image_data = image_remote_list(host_id)
        if not res2:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=local_image_data)
        else:
            #获取当前库中任务存在的镜像任务
            host_info = host_s.HostService().get_host_info(host_id)
            host_ip = host_info['ipaddress']
            image_task_list = im_sy_s.get_host_working_list(host_ip)
            #分别对local_image_list和remote_image_list做处理
            local_image_data_ch = local_image_list_ch(host_id,
                                                      local_image_data,
                                                      image_task_list)
            remote_image_data_ch = remote_image_list_ch(
                remote_image_data, image_task_list)
            return_data = {
                'local_image_data': local_image_data_ch,
                'remote_image_data': remote_image_data_ch
            }
            return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                               data=return_data)
예제 #7
0
def image_status_check(image_name,host_id):
    host_data = host_s.HostService().get_host_info(host_id)
    if not host_data:
        message = "获取host信息失败"
        return False, message
    res, image_data = im_s.ImageService().get_images_by_name_t(image_name)
    if not res:
        message = "获取镜像信息失败"
        return False, message
    image_local_md5,message  = image_md5_get(host_data['ipaddress'],image_name)
    if not image_local_md5:
        return False,False,message
    else:
        res, image_data = im_s.ImageService().get_images_by_name_t(image_name)
        if not res:
            message = '镜像:%s不在远端镜像列表中' %image_name
            return False,'1',message
        else:
            image_remote_md5 = image_data[0]['md5']
            if image_local_md5 == image_remote_md5:
                message = "镜像为最新"
                return True,'0',message
            else:
                message = "镜像需更新"
                return True,'1',message
def __update_host_table(host_ip, ostype, cpu_core, mem_size, disk_size,
                        net_size, current_cpu_used, current_mem_used,
                        current_disk_used, week_cpu_p95_used,
                        week_mem_p95_used, current_net_rx_used,
                        current_net_tx_used, start_time, libvirt_port, images,
                        libvirt_status):
    _update_data_h = {
        'host_performance_collect_time': get_datetime_str(),
        'ostype': ostype,
        'cpu_core': cpu_core,
        'mem_size': mem_size,
        'disk_size': disk_size,
        'net_size': net_size,
        'current_cpu_used': current_cpu_used,
        'current_mem_used': current_mem_used,
        'current_disk_used': current_disk_used,
        'week_cpu_p95_used': week_cpu_p95_used,
        'week_mem_p95_used': week_mem_p95_used,
        'current_net_rx_used': current_net_rx_used,
        'current_net_tx_used': current_net_tx_used,
        'start_time': start_time,
        'libvirt_port': libvirt_port,
        'images': images,
        'libvirt_status': libvirt_status
    }
    _where_data_h = {'ipaddress': host_ip, 'isdeleted': '0'}
    host_s.HostService().update_host_info(_update_data_h, _where_data_h)
    return 'done'
예제 #9
0
def host_update(host_id):
    name = request.values.get('name')
    ip_address = request.values.get('ip_address')
    hold_mem_gb = request.values.get('hold_mem_gb')
    manage_ip = request.values.get('manage_ip')

    if not host_id or not name or not ip_address or not hold_mem_gb or not manage_ip:
        logging.error('the params is invalid when update host')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    host_data = host_s.HostService().get_host_info(host_id)
    if not host_data:
        logging.error('the host %s is no exist in db when update host',
                      host_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    if host_data['manage_ip'] != manage_ip:
        # 管理IP对应的host数据已存在
        host_data = host_s.HostService().get_host_info_by_manage_ip(manage_ip)
        if host_data:
            logging.info('manage ip %s to host is exist', manage_ip)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg="该HOST数据已存在,不能重复创建")

    update_data = {
        'name': name,
        'displayname': name,
        'ipaddress': ip_address,
        'hold_mem_gb': hold_mem_gb,
        'manage_ip': manage_ip,
        'updated_at': get_datetime_str()
    }
    where_data = {
        'id': host_id,
    }
    ret = host_s.HostService().update_host_info(update_data, where_data)
    if ret < 0:
        logging.error("update host error, update_data:%s, where_data:%s",
                      str(update_data), str(where_data))
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR)

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
예제 #10
0
def get_host_detail(host_id):
    '''
        获取host详情
    :param host_id:
    :return:
    '''
    if not host_id:
        logging.info('no host_id when get host detail')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    host_db = host_s.HostService().get_host_info(host_id)
    if not host_db:
        logging.info('host %s no exist in db when get host detail', host_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg="不存在该物理机信息")

    host = host_info.HostInfo()
    host.displayname = host_db['displayname']
    host.ipaddress = host_db['ipaddress']
    host.manage_ip = host_db['manage_ip']
    host.status = host_db['status']
    host.hold_mem_gb = host_db['hold_mem_gb']
    host.sn = host_db['sn']
    host.ostype = host_db['ostype']

    # host性能数据
    host_perform_info = host_s_s.get_host_used(host_db, expire=False)
    if host_perform_info:
        host.cpu_core = host_perform_info.get('cpu_core', 'unknown')
        host.current_cpu_used = host_perform_info.get('current_cpu_used',
                                                      'unknown')
        host.mem_size = host_perform_info.get('mem_size', 'unknown')
        host.current_mem_used = host_perform_info.get('current_mem_used',
                                                      'unknown')
        host.disk_size = host_perform_info.get('disk_size', 'unknown')
        host.current_disk_used = host_perform_info.get('current_disk_used',
                                                       'unknown')
        host.collect_time = host_perform_info['collect_time']
        host.start_time = host_perform_info['start_time']
        host.images = host_perform_info.get('images', 'unknown')
        host.libvirt_status = host_perform_info.get('libvirt_status',
                                                    'unknown')
        host.libvirt_port = host_perform_info.get('libvirt_port', 'unknown')

    host_level_info = host_s.get_level_info(host_db['id'])
    if host_level_info:
        host.hostpool = host_level_info['hostpool_name']
        host.net_area = host_level_info['net_area_name']
        host.datacenter = host_level_info['datacenter_name']
    host.instance_nums = ins_s.get_instances_nums_in_host(host_db['id'])

    # todo: libvirtd状态、服务端口,物理机开机时间、os版本、镜像数量、卷存储路径、序列号
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                       data=host.to_json())
def update_host_table_time(host_ip):
    _update_data_h = {
        'host_performance_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 host data, update_data:%s, where_data:%s',
                      _update_data_h, _where_data_h)
    return 'done'
예제 #12
0
def __check_host_capacity(host_data, n_flavor, c_flavor, extend_list=None):
    '''
        检查物理机容量是否满足扩容
    :param host_data:
    :param n_flavor:
    :param c_flavor:
    :param extend_list:
    :return:
    '''

    # 新配额信息
    n_cpu = int(n_flavor['vcpu'])
    n_mem_mb = int(n_flavor['memory_mb'])
    # 旧配额信息
    c_cpu = int(c_flavor['vcpu'])
    c_mem_mb = int(c_flavor['memory_mb'])

    # 虚拟机配额增量赋值
    increase_cpu = 0
    increase_mem_mb = 0

    if n_cpu > c_cpu:
        increase_cpu = n_cpu - c_cpu

    if n_mem_mb > c_mem_mb:
        increase_mem_mb = n_mem_mb - c_mem_mb

    if extend_list:
        increase_disk_gb = sum([int(i['mount_extend_size']) for i in extend_list])
    else:
        increase_disk_gb = 0

    # VM分配给HOST看是否满足迁移
    vm = {
        "vcpu": increase_cpu,
        "mem_MB": increase_mem_mb,
        "disk_GB": increase_disk_gb,
    }

    # 获取物理机所在资源池可用物理机数量
    all_hosts_nums, all_hosts_data = host_s.HostService().get_available_hosts_of_hostpool(host_data["hostpool_id"])
    if all_hosts_nums < 1:
        return False, '物理机资源不足,无法满足虚拟机配置修改'
    host_datas = []
    host_datas.append(host_data)
    host_after_match, ret_msg = host_s_s.configuare_filter_host(host_datas, vm, all_hosts_nums, max_disk=2000)
    if len(host_after_match) == 0:
        return False, ret_msg

    return True, ret_msg
예제 #13
0
 def _filter_least_host_num(hostpool_id, least_host_num):
     '''
         过滤掉不满足最少host数的集群
     :param hostpool_id:
     :param least_host_num:
     :return:
     '''
     # 获取主机列表
     all_hosts_nums, all_hosts_data = host_s.HostService().get_hosts_of_hostpool(hostpool_id)
     if all_hosts_nums < least_host_num or all_hosts_nums < 1:
         logging.info('filter hostpool %s that has no least host nums %s when get create init info',
                      hostpool_id, least_host_num)
         return False
     return True
예제 #14
0
def image_sync_host():
    resp = image_sync_host_list()

    # area层级信息 - 总部
    area_ZB, area_DQ = v2v_esx_get_hostpool_info()
    if area_ZB != []:
        for single_area in area_ZB:
            hostpool_id = single_area['hostpool_id']
            params = {
                'WHERE_AND': {
                    "=": {
                        'isdeleted': '0',
                        'hostpool_id': hostpool_id
                    }
                },
            }
            host_data_list = host_s.HostService().query_data(**params)[1]
            single_area['host_data'] = host_data_list

    if area_DQ != []:
        for single_area in area_DQ:
            hostpool_id = single_area['hostpool_id']
            params = {
                'WHERE_AND': {
                    "=": {
                        'isdeleted': '0',
                        'hostpool_id': hostpool_id
                    }
                },
            }
            host_data_list = host_s.HostService().query_data(**params)[1]
            single_area['host_data'] = host_data_list

    resp.area_ZB = area_ZB
    resp.area_DQ = area_DQ
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS,
                                       data=resp.to_json())
예제 #15
0
def single_host_return(host_id,image_list):
    #获取当前host已有的镜像信息汇总
    res1,local_image_data = local_image_return(host_id)
    #获取当前库中任务存在的镜像任务
    host_info = host_s.HostService().get_host_info(host_id)
    host_ip = host_info['ipaddress']
    image_task_list = im_sy_s.get_host_working_list(host_ip)
    #对local_image_list做处理,更新当前的local_image_list
    local_image_data_ch = local_image_list_ch(host_id,local_image_data,image_task_list)
    #对远端的image_list针对local_image_list做筛选判断
    res,return_list = local_image_list_return(local_image_data_ch,image_list,host_id)
    if not res:
        msg = 'host上镜像获取失败'
        return False,msg
    else:
        return True,return_list
예제 #16
0
def get_host_local_image(host_id):
    host_db = host_s.HostService().get_host_info(host_id)
    if not host_db:
        message = '该物理机不存在'
        return False,message
    host = host_info.HostInfo()
    host_perform_info = host_s_s.get_host_used(host_db, expire=False)
    if not host_perform_info:
        message = '获取镜像信息失败'
        return False,message
    host.collect_time = host_perform_info['collect_time']
    host.start_time = host_perform_info['start_time']
    host_images = host_perform_info['images']
    if host_images == '':
        local_image_list = []
    else:
        local_image_list = host_images.split(' ')
    return True,local_image_list
예제 #17
0
def image_task_get(host_id, image_id):
    host_ip = host_s.HostService().get_host_info(host_id)['ipaddress']
    #查询db,获取当前host上的任务信息
    res_data = im_sy_s.get_ondo_task(host_ip, image_id)
    if res_data:
        image_sy_type = res_data[0]['type']
        image_sy_stat = res_data[0]['status']
        image_sy_id = res_data[0]['id']
        image_sy_speed = res_data[0]['speed_limit']

        # 如果是立即执行的任务,则返回任务开始时间
        if image_sy_type == "0":
            task_startime = im_sy_s.get_task_startttime(image_sy_id)
            res1_data = {
                'host_ip': host_ip,
                'ondo_task': '0',
                'task_type': image_sy_type,
                'start_time': task_startime,
                'task_state': image_sy_stat
            }
            return res1_data
        # 如果是计划任务,则返回每个计划任务的情况
        else:
            task_startime = im_sy_s.get_task_startttime(image_sy_id)
            sch_ondo_num, sch_ondo_list = im_sy_sch.get_ondo_sch_list(
                image_sy_id)
            res2_data = {
                'host_ip': host_ip,
                'ondo_task': '0',
                'task_type': image_sy_type,
                'start_time': task_startime,
                'task_state': image_sy_stat,
                'task_sch_ondo_list': sch_ondo_list,
                'speed_limit': image_sy_speed,
                'task_sch_ondo_num': sch_ondo_num
            }
            return res2_data
    # 如果host无进行中状态的任务,则返回host_ip给前端
    else:
        res3_data = {
            'ondo_task': '1',
            'host_ip': host_ip,
        }
        return res3_data
예제 #18
0
def image_task_get(host_id, image_id):
    host_ip = host_s.HostService().get_host_info(host_id)['ipaddress']
    #查询db,获取当前host上的任务信息
    res_data = im_sy_s.get_ondo_task(host_ip, image_id)
    task_time_list = []
    if res_data:
        image_sy_type = res_data[0]['type']
        image_sy_id = res_data[0]['id']
        # 如果是计划任务,则记录任务的时间到list中
        if image_sy_type != "0":
            sch_ondo_num, sch_ondo_data_list = im_sy_sch.get_ondo_sch_list(
                image_sy_id)
            if sch_ondo_num > 0:
                for sch_data in sch_ondo_data_list:
                    insert_data = {
                        'sch_starttime': sch_data['sch_starttime'],
                        'sch_endtime': sch_data['sch_endtime']
                    }
                    task_time_list.append(insert_data)
    return task_time_list
예제 #19
0
def get_host_used_by_hostip(host_ip, expire=True, expire_time=600):
    '''
        获取host资源使用情况
    :param host_ip:
    :param expire:设置True,表示获取性能数据时要考虑收集时间
    :param expire_time:超过过期时间,则认为性能数据不准确,不予采用
    :return:
    '''
    # 获取性能数据
    used_data = host_s.HostService().get_host_info_by_hostip(host_ip)
    if not used_data:
        logging.error('the host %s perform data can not get in db', host_ip)
        return None

    if expire and check_collect_time_out_interval(
            used_data['host_performance_collect_time'], expire_time):
        logging.error('the host %s perform data is expire', host_ip)
        return None

    return used_data
예제 #20
0
def get_host_used(host, expire=True, expire_time=600):
    '''
        获取host资源使用情况
    :param host:
    :param expire:设置True,表示获取性能数据时要考虑收集时间
    :param expire_time:超过过期时间,则认为性能数据不准确,不予采用
    :return:
    '''
    host_ip = host['ipaddress']
    # 获取性能数据
    used_data = host_s.HostService().get_host_info_by_hostip(host_ip)
    if not used_data:
        logging.error('the host %s perform data not in a time', host_ip)
        return None

    if expire and check_collect_time_out_interval(
            used_data['host_performance_collect_time'], expire_time):
        logging.error('the host %s perform data is expire', host_ip)
        return None

    # 获取db中数据
    # host_info = host_s.HostService().get_host_info_by_sn(host['sn'])
    # if host_info and used_data:
    used_data['host_id'] = used_data['id']
    # used_data['sn'] = used_data['sn']
    used_data['type_status'] = used_data['typestatus']
    # used_data['hold_mem_gb'] = host_info['hold_mem_gb']
    # used_data['name'] = host_info['name']
    # used_data['ipaddress'] = host_info['ipaddress']
    # used_data['libvirtd_status'] = host_info['libvirtd_status']
    used_data['collect_time'] = used_data['host_performance_collect_time']
    used_data['ip'] = used_data['ipaddress']
    used_data['hostname'] = used_data['name']
    # 获取host下所有vm分配的mem、vcpu、qdisk
    used_data['assign_mem'] = host_s.get_vm_assign_mem_of_host(used_data['id'])
    used_data['assign_vcpu'] = host_s.get_vm_assign_vcpu_of_host(
        used_data['id'])
    used_data['assign_disk'] = host_s.get_vm_assign_disk_of_host(
        used_data['id'])

    return used_data
예제 #21
0
def hostpool_delete():
    hostpool_ids = request.values.get('hostpool_ids')
    if not hostpool_ids:
        logging.error('no hostpool_ids when delete hostpool')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR)

    hostpool_ids_list = hostpool_ids.split(',')
    # 操作的hostpool数
    all_num = len(hostpool_ids_list)
    msg = None
    fail_num = 0
    for _id in hostpool_ids_list:
        _hosts_nums = host_s.HostService().get_hosts_nums_of_hostpool(_id)
        if _hosts_nums > 0:
            logging.error('no allow to delete hostpool %s that has host', _id)
            fail_num += 1
            # 单台操作且已失败则直接跳出循环
            if all_num == 1:
                msg = '该集群下已分配有HOST,不允许删除'
                break
            continue

        _ret = hostpool_s.HostPoolService().delete_hostpool(_id)
        if _ret <= 0:
            logging.error('db delete hostpool %s fail when delete hostpool')
            fail_num += 1
            continue

    # 全失败
    if fail_num == all_num:
        logging.error("delete hostpool 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("delete hostpool part failed")
        return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART,
                                           msg="部分集群删除成功")
    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
예제 #22
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())
예제 #23
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)
예제 #24
0
def host_image_task_intodb():
    #获取单台host的入库信息
    front_data = request.get_data()
    front_data_dict = json.loads(front_data)
    host_id = front_data_dict['host_id']
    image_list = front_data_dict['image_list']
    if not host_id or not image_list:
        err_msg = '入参缺失'
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=err_msg)
    #判断host_id是否异常
    host_data = host_s.HostService().get_host_info(host_id)
    host_ip = host_data['ipaddress']
    if not host_data:
        err_msg = '获取host信息失败'
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=err_msg)
    #定义两个list来存成功的image_task和失败的image_task
    correct_image_task_list = []
    error_image_task_list = []

    # #判断前台发来的image_list总长度不能大于7
    # image_list_num = len(image_list)
    # if int(image_list_num) > 7 :
    #     err_msg = 'image任务数量不能大于7'
    #     return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=err_msg)

    #判断前台传输的image id信息是否有重复值
    image_id_rep_check = image_id_check_rep(image_list)
    if not image_id_rep_check:
        err_msg = '同步任务中出现重复的image id记录'
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=err_msg)

    # 判断镜像信息是否异常
    for image_task_info in image_list:
        image_id = image_task_info['image_id']
        image_info = im_s.ImageService().get_image_info(image_id)
        #如果判断image_id异常
        if not image_info:
            err_msg = '获取镜像id为' + image_id + '信息失败'
            err_data = {
                'image_task': image_task_info,
                'error_message': err_msg
            }
            error_image_task_list.append(err_data)
            image_list.remove(image_task_info)
        else:
            #判断新增任务时间是否异常
            res, msg = check_new_task_time(image_task_info, host_id, image_id)
            if not res:
                err_msg = msg
                err_data = {
                    'image_task': image_task_info,
                    'error_message': err_msg
                }
                error_image_task_list.append(err_data)
                image_list.remove(image_task_info)
                print 1

    #针对check后的任务清单做入库处理
    for image_task_info in image_list:
        # 判断任务是新增还是加入计划任务
        image_id = image_task_info['image_id']
        image_task_ondo = im_sy_s.get_ondo_task(host_ip, image_id)
        #如果为新增任务
        if not image_task_ondo:
            task_start_time_str = image_task_info['start_time']
            task_start_time = datetime.strptime(task_start_time_str,
                                                "%Y-%m-%d %X")
            task_info_list = image_task_info['task_list']
            task_num = len(task_info_list)
            #判断计划任务数是否大于7
            if task_num > 7:
                image_info = im_s.ImageService().get_image_info(image_id)
                image_name = image_info['name']
                image_descrp = image_info['description']
                err_msg = '该image ' + image_name + ' ' + image_descrp + ' 所添加的计划任务数量大于7'
                err_data = {
                    'error_message': err_msg,
                    'image_task': image_task_info
                }
                error_image_task_list.append(err_data)
                image_list.remove(image_task_info)
            speed_limit = image_task_info['speed_limit']
            host_ip = host_s.HostService().get_host_info(host_id)['ipaddress']
            #将每个image_task入image_sync_task表
            insert_data = {
                'image_id': image_id,
                'host_ip': host_ip,
                'status': '0',
                'type': '1',
                'schedule_num': task_num,
                'start_time': task_start_time,
                'isdeleted': '0',
                'on_task': '0',
                'speed_limit': speed_limit,
                'process_id': 'undefined'
            }
            res1 = im_sy_s.ImageSyncService().add_image_sync_task(insert_data)
            if not res1:
                message = '插入image_sync_task表失败'
                err_data = {
                    'image_task': image_task_info,
                    'error_message': message
                }
                error_image_task_list.append(err_data)
                image_list.remove(image_task_info)
            #如入image_sync_task表成功,则继续入image_sync_schedult表
            else:
                image_sync_task_id = res1.get('last_id')
                for sch_task in task_info_list:
                    sch_starttime_str = sch_task['sch_starttime']
                    sch_endtime_str = sch_task['sch_endtime']
                    sch_starttime = datetime.strptime(sch_starttime_str,
                                                      "%Y-%m-%d %X")
                    sch_endtime = datetime.strptime(sch_endtime_str,
                                                    "%Y-%m-%d %X")
                    insert_data = {
                        'image_task_id': image_sync_task_id,
                        'sch_state': '0',
                        'sch_starttime': sch_starttime,
                        'sch_endtime': sch_endtime,
                        'isdeleted': '0'
                    }
                    res = im_sy_sch.ImageSyncScheduleService(
                    ).add_image_sync_sch(insert_data)
                    #如果入库失败则跳出循环并将上步入库的task_sync表的isdeleted置为1
                    if not res:
                        where_data = {'id': image_sync_task_id}
                        update_data = {'isdeleted': '1'}
                        im_sy_s.ImageSyncService().update_image_sync_task(
                            update_data, where_data)
                        err_msg = '插入计划任务失败'
                        err_data = {
                            'error_message': err_msg,
                            'image_task': image_task_info
                        }
                        error_image_task_list.append(err_data)
                        image_list.remove(image_task_info)
                        error_image_task_list.append(err_data)
                        break

        #如果已存在image_id,只是新增计划任务
        else:
            #获取当前image_id下在running的计划任务数
            image_sync_task_id = image_task_ondo[0]['id']
            sch_ondo_num, sch_ondo_data = im_sy_sch.get_ondo_sch_list(
                image_sync_task_id)
            #判断前台输入的image任务数量是否大于当前可添加的数量
            sch_add_num = len(image_task_info['task_list'])
            if sch_add_num + sch_ondo_num > 7:
                image_info = im_s.ImageService().get_image_info(image_id)
                image_name = image_info['name']
                image_descrp = image_info['description']
                message = '镜像' + image_name + ' ' + image_descrp + '可添加任务数量大于最大值'
                err_data = {
                    'image_task': image_task_info,
                    'error_message': message
                }
                error_image_task_list.append(err_data)
                image_list.remove(image_task_info)
            #如果前台输入的计划任务数量不超过最大值则入库
            else:
                task_info_list = image_task_info['task_list']
                for sch_task in task_info_list:
                    sch_starttime_str = sch_task['sch_starttime']
                    sch_endtime_str = sch_task['sch_endtime']
                    sch_starttime = datetime.strptime(sch_starttime_str,
                                                      "%Y-%m-%d %X")
                    sch_endtime = datetime.strptime(sch_endtime_str,
                                                    "%Y-%m-%d %X")
                    insert_data = {
                        'image_task_id': image_sync_task_id,
                        'sch_state': '0',
                        'sch_starttime': sch_starttime,
                        'sch_endtime': sch_endtime,
                        'isdeleted': '0'
                    }
                    im_sy_sch.ImageSyncScheduleService().add_image_sync_sch(
                        insert_data)

    #统计总的入库成功list和失败list并返回给前台
    for image_task in image_list:
        correct_image_task_list.append(image_task)
    #计算总的失败数
    total_image_task_num = len(image_list)
    total_fail_task_num = len(error_image_task_list)
    if total_image_task_num == 0:
        tag = ErrorCode.ALL_FAIL
    else:
        tag = ErrorCode.SUCCESS
    return_data = {
        'fail_task_num': str(total_fail_task_num),
        'fail_task_list': error_image_task_list,
        'succss_task_list': correct_image_task_list
    }
    return json_helper.format_api_resp(code=tag, data=return_data)
예제 #25
0
def instance_create(hostpool_id):
    '''
        创建虚机
    :param hostpool_id:
    :return:
    '''
    image_name = request.values.get('image_name')
    flavor_id = request.values.get('flavor_id')
    disk_gb = request.values.get('disk_gb')
    count = request.values.get('count')
    app_info = request.values.get('app_info')
    group_id = request.values.get('group_id')
    owner = request.values.get('owner')
    password = request.values.get('password')
    task_id = ins_s.generate_task_id()

    logging.info(
        '创建VM 步骤1:检查参数 task %s : check params start when create instance',
        task_id)

    if not hostpool_id or not image_name or not flavor_id or not disk_gb or not group_id \
            or not count or int(count) < 1:
        logging.error(
            '创建VM 步骤1:检查参数失败 参数错误 task %s : params are invalid when create instance',
            task_id)
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg='参数错误')

    if int(count) > int(INSTANCE_MAX_CREATE):
        logging.error(
            '创建VM 步骤1:检查参数失败 批量创建数超过最大数 '
            'task %s : create count %s > max num %s when create instance',
            task_id, count, INSTANCE_MAX_CREATE)
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg='批量创建最大实例数不能超过' +
                                           INSTANCE_MAX_CREATE + '个')

    owner_exist = user_s.UserService().check_userid_exist(owner)
    if not owner_exist:
        logging.error(
            '创建VM 步骤1:检查参数失败 应用管理员工号不存在 '
            'task %s : no such user %s in db when create instance', task_id,
            owner)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='应用管理员工号不存在,无法创建实例')

    logging.info(
        '创建VM 步骤1:检查参数成功 task %s : check params successful when create instance',
        task_id)

    # 数据盘最少50GB
    # todo:这里只是一个数据盘,后面有多个数据盘
    vm_disk_gb = int(disk_gb) if int(disk_gb) > DATA_DISK_GB else DATA_DISK_GB

    # 获取主机列表(不包括锁定、维护状态)
    logging.info(
        '创建VM 步骤2:获取集群所有HOST列表 '
        'task %s : get all hosts in hostpool %s start when create instance',
        task_id, hostpool_id)
    all_hosts_nums, all_hosts_data = host_s.HostService(
    ).get_available_hosts_of_hostpool(hostpool_id)
    # 可用物理机数量不足
    least_host_num = hostpool_service.HostPoolService().get_least_host_num(
        hostpool_id)
    if all_hosts_nums < least_host_num or all_hosts_nums < 1:
        logging.error(
            '创建VM 步骤2:获取集群所有HOST列表失败 集群不够资源 '
            'task %s : available host resource not enough when create instance',
            task_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='集群不够资源,无法创建实例')
    logging.info(
        '创建VM 步骤2:获取集群所有HOST列表成功,总host数:%s '
        'task %s : get all hosts in hostpool %s successful, all hosts nums %s when create instance',
        all_hosts_nums, task_id, hostpool_id, all_hosts_nums)

    # 过滤host
    logging.info(
        '创建VM 步骤3:HOST过滤 task %s : filter hosts start when create instance',
        task_id)
    hosts_after_filter = host_s_s.filter_hosts(all_hosts_data)
    if len(hosts_after_filter
           ) == 0 or len(hosts_after_filter) < least_host_num:
        logging.error(
            '创建VM 步骤3:HOST过滤失败 没有合适主机 '
            'task %s : no available host when create instance', task_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='集群物理机资源无法满足你的申请需求,请联系系统组同事')
    logging.info(
        '创建VM 步骤3:HOST过滤成功 task %s : filter hosts successful when create instance',
        task_id)

    # 获取flavor信息
    logging.info(
        '创建VM 步骤4:获取必需信息 task %s : get need info start when create instance',
        task_id)
    flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id)
    if not flavor_info:
        logging.error(
            '创建VM 步骤4:获取必需信息失败 实例规格数据有误 '
            'task %s : flavor %s info not in db when create instance', task_id,
            flavor_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='实例规格数据有误,无法创建实例')

    # VM分配给HOST
    logging.info(
        '创建VM 步骤5:HOST分配 task %s : match hosts start when create instance',
        task_id)
    vm = {
        "vcpu": flavor_info['vcpu'],
        "mem_MB": flavor_info['memory_mb'],
        "disk_GB": flavor_info['root_disk_gb'] + vm_disk_gb,  # 系统盘加数据盘
        "group_id": group_id,
        "count": count
    }
    host_list = host_s_s.match_hosts(hosts_after_filter,
                                     vm,
                                     least_host_num=least_host_num,
                                     max_disk=2000)
    host_len = len(host_list)
    if host_len == 0:
        logging.error(
            '创建VM 步骤5:HOST分配失败 没有合适主机 '
            'task %s : match host resource not enough when create instance',
            task_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='集群物理机资源无法满足你的申请需求,请联系系统组同事')
    logging.info(
        '创建VM 步骤5:HOST分配成功 task %s : match hosts successful when create instance',
        task_id)

    # 获取hostpool的net area信息
    hostpool_info = hostpool_service.HostPoolService().get_hostpool_info(
        hostpool_id)
    if not hostpool_info:
        logging.error(
            '创建VM 步骤6:获取必需信息失败 物理机池所属网络区域信息有误 '
            'task %s : hostpool %s info not in db when create instance',
            task_id, hostpool_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='物理机池所属网络区域信息有误,无法创建实例')

    net_area_id = hostpool_info['net_area_id']
    logging.info(
        '创建VM 步骤6:获取必需信息成功 task %s : get need info successful when create instance',
        task_id)

    # 组配额控制
    logging.info(
        '创建VM 步骤7:检查组配额 task %s : check group quota start when create instance',
        task_id)
    is_quota_enough, quota_msg = check_group_quota(group_id, flavor_info,
                                                   vm_disk_gb, count)
    if not is_quota_enough:
        logging.error(
            '创建VM 步骤7:检查组配额失败 配额不足 '
            'task %s : group %s is no enough quota when create instance',
            task_id, group_id)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg=quota_msg)
    logging.info(
        '创建VM 步骤7:检查组配额成功 task %s : check group quota successful when create instance',
        task_id)

    logging.info(
        '创建VM 步骤8:获取必需信息 task %s : get need 1 info start when create instance',
        task_id)
    # 获取镜像信息,一个image_name可能对应多个id
    image_nums, image_data = image_service.ImageService().get_images_by_name(
        image_name)
    if image_nums <= 0:
        logging.info(
            '创建VM 步骤8:获取必需信息失败 镜像资源不足 '
            'task %s : no image %s info in db when create instance', task_id,
            image_name)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='没有镜像资源,无法创建实例')

    # 实例操作系统
    instance_system = image_data[0]['system']
    logging.info(
        '创建VM 步骤8:获取必需信息成功 '
        'task %s : get need 1 info successful when create instance', task_id)

    # 获取集群所在的环境
    vm_env = hostpool_service.get_env_of_hostpool(hostpool_id)
    # hostpool对应的机房名
    dc_name = hostpool_service.get_dc_name_of_hostpool(hostpool_id)
    # 获取集群所在网络区域名
    net_area_name = hostpool_service.get_level_info_by_id(hostpool_id).get(
        'net_area_name', '')

    # 获取虚机名资源
    logging.info(
        '创建VM 步骤9:获取主机名资源 '
        'task %s : check instance name resource start when create instance',
        task_id)
    is_name_enough, instance_name_list = _check_instance_name_resource(
        vm_env, dc_name, instance_system, count)
    if not is_name_enough:
        logging.error(
            '创建VM 步骤9:获取主机名资源失败 主机名资源不足 '
            'task %s : datacenter %s has no enough instance name resource',
            task_id, dc_name)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg='主机名资源不足,无法创建实例')
    logging.info(
        '创建VM 步骤9:获取主机名资源成功 '
        'task %s : check instance name resource successful when create instance',
        task_id)

    # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化
    ip_lock_unused = False
    while not ip_lock_unused:
        ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip')
        if not ret_ip_lock_status:
            logging.error(
                '创建VM 步骤10:检查IP时无法获取资源锁状态'
                'task %s : check ip resource can not get lock', task_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='检查IP时无法获取资源锁状态')
        if ret_ip_lock_status['istraceing'] == IpLockStatus.USED:
            time.sleep(1)
        else:
            ip_lock_unused = True

    # 更新ip_lock表istraceing字段为1
    ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used()
    if not ret_ip_lock_used_status:
        logging.error(ret_ip_lock_used_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_used_datas)
    try:
        ret_ips_status, ret_ips_data, ret_segment = __check_ip_resource(
            vm_env, dc_name, net_area_name, count)
    except Exception as e:
        _msg = '创建VM 步骤10:检查IP资源是否足够出现异常task_id %s: check ip resource exception when instance create,err:%s' % (
            task_id, e)
        logging.error(_msg)
        ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused(
        )
        if not ret_ip_lock_unused_status:
            logging.error(ret_ip_lock_unused_datas)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=ret_ip_lock_unused_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg)

    if not ret_ips_status:
        ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused(
        )
        if not ret_ip_lock_unused_status:
            logging.error(ret_ip_lock_unused_datas)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=ret_ip_lock_unused_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg=ret_ips_data)

    # 更新ip_lock表istraceing字段为0
    ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused(
    )
    if not ret_ip_lock_unused_status:
        logging.error(ret_ip_lock_unused_datas)
        return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                           msg=ret_ip_lock_unused_datas)

    ips_list = ret_ips_data
    segment_data = ret_segment
    logging.info(
        '创建VM 步骤10:检查IP资源成功 task %s : check ip resource successful when create instance',
        task_id)

    # 挂载点
    if instance_system == 'linux':
        mount_point = '/app'
    else:
        mount_point = 'E'

    logging.info(
        '创建VM 步骤11:多线程发送创建信息 task %s : create thread start when create instance',
        task_id)
    user_id = get_user()['user_id']
    all_threads = []
    for i in range(int(count)):
        instance_name = str(instance_name_list[i])
        ip_data = ips_list[i]

        # 轮询host
        index = i % host_len
        vm_host = host_list[index]

        create_ins_t = threading.Thread(
            target=_create_instance_info,
            args=(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),
            name='thread-instance-create-' + task_id)
        all_threads.append(create_ins_t)
        create_ins_t.start()

    for thread in all_threads:
        thread.join()

    logging.info(
        '创建VM 步骤11:多线程发送创建信息成功 '
        'task %s : create thread successful when create instance', task_id)

    return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def _task_into_db(task):
    # 入参赋值
    vmname = task['vm_name']
    vmip = task['vm_ip']
    flavor_id = task['flavor_id']
    cloudarea = task['cloud_area']
    vm_ostype = task['vm_ostype']
    vm_app_info = task['vm_app_info']
    vm_owner = task['vm_owner']
    vm_group_id = task['group_id']
    user_id = task['user_id']
    vm_segment = task['segment']
    vm_disk = task['vm_disk']
    vm_osver = task['vm_osver']
    host = task['dest_host']

    # 入参完全性判断
    if not vmname or not vmip or not flavor_id or not cloudarea or not vm_ostype \
            or not vm_app_info or not vm_owner or not vm_group_id or not user_id or not vm_segment:
        logging.info('params are invalid or missing')
        message = '入参缺失'
        return False, message
    else:
        # 获取flavor信息
        flavor_info = flavor_s.FlavorService().get_flavor_info(flavor_id)
        if not flavor_info:
            logging.info('id: %s flavor info not in db when create instance',
                         flavor_id)
            message = '实例规格数据有误,无法进行v2v'
            return False, message
        vmcpu = flavor_info['vcpu']
        vmmem = flavor_info['memory_mb']

        vmhost = ho_s.HostService().get_host_info_by_hostip(host)
        ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], vmcpu, vmmem, 50)
        if ret_4 != 1:
            logging.error('资源预分配失败')
            message = '资源预分频失败'
            return False, message

        # 获取并录入IP信息
        vm_segment = segment_s.SegmentService().get_segment_info_bysegment(
            vm_segment)
        if vm_segment is None:
            message = '网段信息有误,无法进行v2v'
            return False, message
        else:
            segment_id = vm_segment['id']
            vm_netmask = vm_segment['netmask']
            vm_gateway = vm_segment['gateway_ip']
            vm_dns1 = vm_segment['dns1']
            vm_dns2 = vm_segment['dns2']
            vmvlan = vm_segment['vlan']
            ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
            if ip_data is None:
                ip_data = {
                    'ip_address': vmip,
                    'segment_id': segment_id,
                    'netmask': vm_netmask,
                    'vlan': vmvlan,
                    'gateway_ip': vm_gateway,
                    'dns1': vm_dns1,
                    'dns2': vm_dns2,
                    'created_at': get_datetime_str(),
                    'status': '1'
                }
                ret = ip_s.IPService().add_ip_info(ip_data)
                if ret.get('row_num') <= 0:
                    logging.info(
                        'add ip info error when create v2v task, insert_data: %s',
                        ip_data)
                    message = "录入IP信息失败"
                    return False, message
                else:
                    ip_id = ret.get('last_id')
            else:
                ip_data_status = ip_data['status']
                vmvlan = ip_data['vlan']
                if ip_data_status != '0':
                    message = "IP与现有环境冲突,无法进行v2v"
                    return False, message
                else:
                    ip_id = ip_data['id']
                    where_data = {'id': ip_id}
                    updata_data = {
                        'status': '1',
                        'updated_at': get_datetime_str()
                    }
                    ret1 = ip_s.IPService().update_ip_info(
                        updata_data, where_data)
                    if not ret1:
                        logging.info(
                            'update ip info error when create v2v task, update_data: %s',
                            updata_data)
                        message = "更新IP状态失败"
                        return False, message

        # 生成request_id
        request_id = v2v_op.generate_req_id()

        # 生成vm的uuid和mac
        vmuuid = randomUUID()
        vmmac = randomMAC()

        # 信息入instance相关库表
        instance_tag, instance_info = _instance_db_info(
            vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id,
            host, vmmac, vm_disk, ip_id, vm_ostype, request_id, vm_osver)
        if not instance_tag:
            message = instance_info
            return False, message

        # 将步骤信息存入instance_action表
        # 将createdir信息存入instance_action表
        v2v_cd_d1 = {
            'action': v2vActions.CREATE_DEST_DIR,
            'request_id': request_id,
            'message': 'start',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1)

        # 将getfile信息存入instance_action表
        v2v_gf_d1 = {
            'action': v2vActions.GET_VM_FILE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_gf_d1)

        # 将copy disk信息存入instance_action表
        v2v_cpd_d1 = {
            'action': v2vActions.COPY_VM_DISK,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cpd_d1)

        # 将copy xml信息存入instance_action表
        v2v_cpx_d1 = {
            'action': v2vActions.COPY_VM_XML,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cpx_d1)

        # 将创建存储池信息存入instance_action表
        v2v_csp_d1 = {
            'action': v2vActions.CREATE_STOR_POOL,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_csp_d1)

        # 将vm标准化信息存入instance_action表
        v2v_vmd_d1 = {
            'action': v2vActions.VM_STANDARDLIZE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmd_d1)

        # 将vm注册信息存入instance_action表
        v2v_vmdef_d1 = {
            'action': v2vActions.VM_DEFINE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmdef_d1)

        # 将IP注入信息存入instance_action表
        v2v_vmipj_d1 = {
            'action': v2vActions.IP_INJECT,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_vmipj_d1)

        # 将vm开机信息存入instance_action表
        v2v_vmstar_d1 = {
            'action': v2vActions.VM_START,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_vmstar_d1)

        message = '信息已添加至任务队列,等待执行'

        # 将v2v信息存入v2v_task表
        v2v_data = {
            'request_id': request_id,
            'destory': '0',
            'start_time': get_datetime_str(),
            'status': 0,
            'vm_ip': vmip,
            'vm_name': vmname,
            'vmvlan': vmvlan,
            'flavor_id': flavor_id,
            'cloud_area': cloudarea,
            'vm_ostype': vm_ostype,
            'vm_app_info': vm_app_info,
            'vm_owner': vm_owner,
            'vm_group_id': vm_group_id,
            'user_id': user_id,
            'vm_mac': vmmac,
            'vm_uuid': vmuuid,
            'cancel': '0',
            'dest_dir': '/app/image/' + vmuuid,
            'on_task': '0',
            'port': '10000',
            'source': VMCreateSource.OPENSTACK
        }
        v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data)

        if v2v_insert.get('row_num') <= 0:
            logging.info('insert info to v2v_task failed! %s', v2v_data)
            message = '信息入库失败'
            return False, message

        # 将目标kvmhost存入信息表
        v2v_op.update_v2v_desthost(request_id, host)

        v2v_op.update_v2v_step(request_id, v2vActions.BEGIN)
        return True, message
예제 #27
0
def v2v_esx_intodb(hostpool_id):
    '''
                v2v_esx
            :param hostpool_id:
            :return:
    '''

    #获取vm入库信息
    vmname = request.values.get('vm_name')
    vmip = request.values.get('vm_ip')
    flavor_id = request.values.get('flavor_id')
    vm_ostype = request.values.get('vm_ostype')
    vm_app_info = request.values.get('vm_app_info')
    vm_owner = request.values.get('vm_owner')
    vm_group_id = request.values.get('vm_group_id')
    user_id = request.values.get('user_id')
    vm_segment = request.values.get('segment')
    vm_osver = request.values.get('vm_osver')
    vm_disk = request.values.get('vm_disk')
    esx_env = request.values.get('esx_env')
    esx_ip = request.values.get('esx_ip')
    esx_passwd1 = request.values.get('esx_passwd')
    vmware_vm = request.values.get('vmware_vm')

    # 入参完全性判断
    if not vmname or not vmip  or not flavor_id or not  vm_ostype or not vm_app_info \
        or not vm_osver or not vm_disk  or not vm_owner or not vm_group_id or not user_id or not vm_segment or not esx_passwd1:
        logging.info('params are invalid or missing')
        return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR,
                                           msg='入参缺失')
    else:
        esx_passwd = base64.b64decode(esx_passwd1)
        powertag, msg_power = vm_powerState(esx_ip, esx_passwd, vmware_vm)
        if not powertag:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=msg_power)

        # 获取flavor信息
        flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id)
        if not flavor_info:
            logging.info('id: %s flavor info not in db when create instance',
                         flavor_id)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='实例规格数据有误,无法进行v2v')
        vmcpu = flavor_info['vcpu']
        vmmem = flavor_info['memory_mb']

        data_disk = int(vm_disk)

        # 获取可用目标host

        host_code, host_data, host_msg = cal_host(hostpool_id, vmcpu, vmmem,
                                                  data_disk, vm_group_id)
        if host_code < 0:
            return json_helper.format_api_resp(code=host_code, msg=host_msg)
        else:
            host = host_data

        vmhost = ho_s.HostService().get_host_info_by_hostip(host)
        ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], vmcpu, vmmem, 50)
        if ret_4 != 1:
            logging.error('资源预分配失败')
            message = '资源预分频失败'
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg=message)

        # 获取并录入IP信息

        vm_segment = seg_s.SegmentService().get_segment_info_bysegment(
            vm_segment)
        if vm_segment == None:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='网段信息有误,无法进行v2v')
        else:
            segment_id = vm_segment['id']
            vm_netmask = vm_segment['netmask']
            vm_gateway = vm_segment['gateway_ip']
            vm_dns1 = vm_segment['dns1']
            vm_dns2 = vm_segment['dns2']
            vmvlan = vm_segment['vlan']
            ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
            if ip_data == None:
                ip_data = {
                    'ip_address': vmip,
                    'segment_id': segment_id,
                    'netmask': vm_netmask,
                    'vlan': vmvlan,
                    'gateway_ip': vm_gateway,
                    'dns1': vm_dns1,
                    'dns2': vm_dns2,
                    'created_at': get_datetime_str(),
                    'status': '1'
                }
                ret = ip_s.IPService().add_ip_info(ip_data)
                if ret.get('row_num') <= 0:
                    logging.info(
                        'add ip info error when create v2v task, insert_data: %s',
                        ip_data)
                    return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                       msg="录入IP信息失败")
                else:
                    ip_id = ret.get('last_id')
            else:
                ip_data_status = ip_data['status']
                vmvlan = ip_data['vlan']
                if ip_data_status != '0':
                    return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                                       msg="IP与现有环境冲突,无法进行v2v")
                else:
                    ip_id = ip_data['id']
                    where_data = {'id': ip_id}
                    updata_data = {
                        'status': '1',
                        'updated_at': get_datetime_str()
                    }
                    ret1 = ip_s.IPService().update_ip_info(
                        updata_data, where_data)
                    if not ret1:
                        logging.info(
                            'update ip info error when create v2v task, update_data: %s',
                            updata_data)
                        return json_helper.format_api_resp(
                            code=ErrorCode.SYS_ERR, msg="更新IP状态失败")

        # 生成request_id
        request_Id = v2v_op.generate_req_id()

        # 生成vm的uuid和mac
        vmuuid = randomUUID()
        vmmac = randomMAC()

        if not vm_osver:
            vm_osver = "unknown"

        # 信息入instance相关库表
        instance_info = instance_db_info(vmuuid, vmname, vm_app_info, vm_owner,
                                         flavor_id, vm_group_id, host, vmmac,
                                         data_disk, ip_id, vm_ostype,
                                         request_Id, vm_osver)
        if instance_info < 0:
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='信息入库失败')

        #   将步骤信息存入instance_action表
        v2v_cd_d1 = {
            'action': esx_v2vActions.CREATE_DEST_DIR,
            'request_id': request_Id,
            'message': 'start',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1)

        v2v_cr_pl = {
            'action': esx_v2vActions.CREATE_STOR_POOL,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cr_pl)

        v2v_cp_fl = {
            'action': esx_v2vActions.COPY_FILE_TO_LOCAL,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cp_fl)

        v2v_file = {
            'action': esx_v2vActions.VIRT_V2V_FILES,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_file)

        v2v_del_tmp = {
            'action': esx_v2vActions.DELETE_TMP_FILE,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_del_tmp)

        v2v_sysdisk_std = {
            'action': esx_v2vActions.VM_SYS_DISK_STD,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_sysdisk_std)

        v2v_datadisk_std = {
            'action': esx_v2vActions.VM_DATA_DISK_STD,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_datadisk_std)

        v2v_def_1 = {
            'action': esx_v2vActions.VM_DEFINE1,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_def_1)

        v2v_star_1 = {
            'action': esx_v2vActions.VM_START1,
            'request_id': request_Id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_star_1)

        if vm_ostype == "Windows":

            v2v_att_disk = {
                'action': esx_v2vActions.ATTACH_DISK,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_att_disk)

            v2v_win_std = {
                'action': esx_v2vActions.WINDOWS_STD,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_win_std)

            v2v_vm_def2 = {
                'action': esx_v2vActions.WINDOWS_DISK_CH,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_def2)

            v2v_vm_star2 = {
                'action': esx_v2vActions.VM_START2,
                'request_id': request_Id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_star2)

        message = '信息已添加至任务队列,等待执行'

        # 将v2v信息存入v2v_task表
        v2v_data = {
            'source': VMCreateSource.ESX,
            'request_id': request_Id,
            'destory': '0',
            'start_time': get_datetime_str(),
            'status': 0,
            'vm_ip': vmip,
            'vm_name': vmname,
            'vmvlan': vmvlan,
            'flavor_id': flavor_id,
            'cloud_area': esx_env,
            'vm_ostype': vm_ostype,
            'vm_app_info': vm_app_info,
            'vm_owner': vm_owner,
            'vm_group_id': vm_group_id,
            'user_id': user_id,
            'vm_mac': vmmac,
            'vm_uuid': vmuuid,
            'cancel': '0',
            'dest_dir': '/app/image/' + vmuuid,
            'on_task': '0',
            'dest_host': host,
            'esx_ip': esx_ip,
            'esx_passwd': esx_passwd,
            'vmware_vm': vmware_vm,
            'step_done': esx_v2vActions.BEGIN
        }
        v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data)

        if v2v_insert.get('row_num') <= 0:
            logging.info('insert info to v2v_task failed! %s', v2v_data)
            return json_helper.format_api_resp(code=ErrorCode.SYS_ERR,
                                               msg='信息入库失败')

        return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg=message)
예제 #28
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
예제 #29
0
def _task_esx_intodb(task):
    # 获取vm入参
    vmname = task['vm_name']
    vmip = task['vm_ip']
    flavor_id = task['flavor_id']
    vm_ostype = task['vm_ostype']
    vm_app_info = task['vm_app_info']
    vm_owner = task['vm_owner']
    vm_segment = task['vm_segment']
    vm_group_id = task['group_id']
    dest_host = task['dest_host']

    vmhost = ho_s.HostService().get_host_info_by_hostip(dest_host)
    ret_4 = ho_s.pre_allocate_host_resource(vmhost['id'], task['vm_cpu'],
                                            task['vm_mem_mb'], 50)
    if ret_4 != 1:
        logging.error('资源预分配失败')
        message = '资源预分配失败'
        return False, message

    # 获取并录入IP信息
    vm_segment = seg_s.SegmentService().get_segment_info_bysegment(vm_segment)
    if vm_segment is None:
        message = '网段信息有误,无法进行v2v操作'
        return False, message
    else:
        segment_id = vm_segment['id']
        vm_netmask = vm_segment['netmask']
        vm_gateway = vm_segment['gateway_ip']
        vm_dns1 = vm_segment['dns1']
        vm_dns2 = vm_segment['dns2']
        vmvlan = vm_segment['vlan']
        ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip)
        if ip_data is None:
            ip_data = {
                'ip_address': vmip,
                'segment_id': segment_id,
                'netmask': vm_netmask,
                'vlan': vmvlan,
                'gateway_ip': vm_gateway,
                'dns1': vm_dns1,
                'dns2': vm_dns2,
                'created_at': get_datetime_str(),
                'status': '1'
            }
            ret = ip_s.IPService().add_ip_info(ip_data)
            if ret.get('row_num') <= 0:
                logging.info(
                    'add ip info error when create v2v task, insert_data: %s',
                    ip_data)
                message = "录入IP信息失败"
                return False, message
            else:
                ip_id = ret.get('last_id')
        else:
            ip_data_status = ip_data['status']
            vmvlan = ip_data['vlan']
            if ip_data_status != '0':
                message = "IP与现有环境冲突,无法进行v2v操作"
                return False, message
            else:
                ip_id = ip_data['id']
                where_data = {'id': ip_id}
                updata_data = {'status': '1', 'updated_at': get_datetime_str()}
                ret1 = ip_s.IPService().update_ip_info(updata_data, where_data)
                if not ret1:
                    logging.info(
                        'update ip info error when create v2v task, update_data: %s',
                        updata_data)
                    message = "更新IP状态失败"
                    return False, message

        # 生成request_id
        request_id = v2v_op.generate_req_id()

        # 生成vm的uuid和mac
        vmuuid = randomUUID()
        vmmac = randomMAC()

        # 信息入instance相关库表
        instance_tag, instance_info = _instance_db_info(
            vmuuid, vmname, vm_app_info, vm_owner, flavor_id, vm_group_id,
            dest_host, vmmac, task['vm_disk'], ip_id, vm_ostype, request_id,
            task['vm_os_version'])
        if not instance_tag:
            message = instance_info
            return False, message

        # 将步骤信息存入instance_action表
        v2v_cd_d1 = {
            'action': esx_v2vActions.CREATE_DEST_DIR,
            'request_id': request_id,
            'message': 'start',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cd_d1)

        v2v_cr_pl = {
            'action': esx_v2vActions.CREATE_STOR_POOL,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cr_pl)

        v2v_cp_fl = {
            'action': esx_v2vActions.COPY_FILE_TO_LOCAL,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_cp_fl)

        v2v_file = {
            'action': esx_v2vActions.VIRT_V2V_FILES,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_file)

        v2v_del_tmp = {
            'action': esx_v2vActions.DELETE_TMP_FILE,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_del_tmp)

        v2v_sysdisk_std = {
            'action': esx_v2vActions.VM_SYS_DISK_STD,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_sysdisk_std)

        v2v_datadisk_std = {
            'action': esx_v2vActions.VM_DATA_DISK_STD,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(
            v2v_datadisk_std)

        v2v_def_1 = {
            'action': esx_v2vActions.VM_DEFINE1,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_def_1)

        v2v_star_1 = {
            'action': esx_v2vActions.VM_START1,
            'request_id': request_id,
            'message': 'other',
            'start_time': get_datetime_str()
        }
        in_a_s.InstanceActionsServices().add_instance_action_info(v2v_star_1)

        if vm_ostype == "Windows":
            v2v_att_disk = {
                'action': esx_v2vActions.ATTACH_DISK,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_att_disk)

            v2v_win_std = {
                'action': esx_v2vActions.WINDOWS_STD,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_win_std)

            v2v_vm_def2 = {
                'action': esx_v2vActions.WINDOWS_DISK_CH,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_def2)

            v2v_vm_star2 = {
                'action': esx_v2vActions.VM_START2,
                'request_id': request_id,
                'message': 'other',
                'start_time': get_datetime_str()
            }
            in_a_s.InstanceActionsServices().add_instance_action_info(
                v2v_vm_star2)

        # 将v2v信息存入v2v_task表
        v2v_data = {
            'source': VMCreateSource.ESX,
            'request_id': request_id,
            'destory': '0',
            'start_time': get_datetime_str(),
            'status': 0,
            'vm_ip': vmip,
            'vm_name': vmname,
            'vmvlan': vmvlan,
            'flavor_id': flavor_id,
            'cloud_area': task['esx_env'],
            'vm_ostype': vm_ostype,
            'vm_app_info': vm_app_info,
            'vm_owner': vm_owner,
            'vm_group_id': vm_group_id,
            'user_id': task['user_id'],
            'vm_mac': vmmac,
            'vm_uuid': vmuuid,
            'cancel': '0',
            'dest_dir': '/app/image/' + vmuuid,
            'on_task': '0',
            'dest_host': dest_host,
            'esx_ip': task['esx_ip'],
            'esx_passwd': task['esx_passwd'],
            'vmware_vm': task['vmware_vm'],
            'step_done': esx_v2vActions.BEGIN
        }
        v2v_insert = v2v_op.v2vTaskService().add_v2v_task_info(v2v_data)

        if v2v_insert.get('row_num') <= 0:
            logging.info('insert info to v2v_task failed! %s', v2v_data)
            message = '信息入库失败'
            return False, message

        message = '信息已添加至任务队列'
        return True, message
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'