def v2v_esx_init_info(): resp = V2v_esx_InitInfoResp() # area层级信息 - 总部 area_ZB, area_DQ = v2v_esx_get_hostpool_info() resp.area_ZB = area_ZB resp.area_DQ = area_DQ # flavor信息 flavors_nums, flavors_data = flavor_service.FlavorService( ).get_all_flavors() for i in flavors_data: _flavor_info = flavor_init_info.FlavorInitInfo().init_from_db(i) resp.flavors.append(_flavor_info) #网段信息 segmentlist = init_segment() resp.segment = segmentlist # group信息 groups_params = { 'WHERE_AND': { '=': { 'isdeleted': '0' } }, } groups_nums, groups_data = group_service.GroupService().query_data( **groups_params) for i in groups_data: _group_info = group_info.GroupInitInfo().init_from_db_1(i) resp.groups.append(_group_info) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
def _cal_group_host(task_list): vm_mem_count = 0 vm_disk_count = 0 count = len(task_list) # 针对每个分组内的list,计算可用host list for task in task_list: flavor_id = task['flavor_id'] vm_group_id = task['group_id'] vm_disk = task["vm_disk"] hostpool_id = task['hostpool_id'] vm_disk_total = int(vm_disk) + 50 flavor_info = flavor_s.FlavorService().get_flavor_info(flavor_id) vmmem = flavor_info['memory_mb'] vm_mem_count += int(vmmem) vm_disk_count += vm_disk_total code, data, msg = cal_host_batch(hostpool_id, vm_mem_count, vm_disk_count, vm_group_id, count) if code < 0: return False, msg else: host_list = data host_len = len(host_list) # 获取host list后,针对每个vm分配host task_len = len(task_list) for i in range(task_len): task_info = task_list[i] host_index = i % host_len vm_host = host_list[host_index] vm_host_ip = vm_host["ip"] task_info['dest_host'] = vm_host_ip return True, host_list
def cal_group_host(task_list): # 针对每个分组内的list,计算可用host list for task in task_list: flavor_id = task['flavor_id'] vm_group_id = task['group_id'] vm_disk = task["vm_disk"] hostpool_id = task['hostpool_id'] vm_disk_total = int(vm_disk) + 50 flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id) vm_mem = flavor_info['memory_mb'] code, data, msg = cal_host_batch(hostpool_id, vm_mem, vm_disk_total, vm_group_id, 1) if code < 0: task["error_message"] = msg else: host_list = data vm_host = host_list[0] task['dest_host'] = vm_host["ip"] res_task_intodb,msg_task_intodb = task_intodb(task) if not res_task_intodb: task["error_message"] = msg_task_intodb return True, task_list
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_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'] user_id = task['user_id'] vm_segment = task['vm_segment'] esx_env = task['esx_env'] esx_ip = task['esx_ip'] esx_passwd1 = task['esx_passwd'] vmware_vm = task['vmware_vm'] vm_osver = task['vm_osver'] vm_group_id = task['vm_group_id'] dest_host = task['dest_host'] vm_disk = task['vm_disk'] # 入参完全性判断 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_owner or not user_id or not vm_segment or not esx_passwd1: logging.info('params are invalid or missing') message = '入参缺失' return False,message else: esx_passwd = base64.b64decode(esx_passwd1) # 获取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) message = '实例规格数据有误,无法进行v2v' return False,message vmcpu = flavor_info['vcpu'] vmmem = flavor_info['memory_mb'] host = dest_host 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 = seg_s.SegmentService().get_segment_info_bysegment(vm_segment) if vm_segment == 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 == 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表 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': 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) message = '信息入库失败' return False,message message = '信息已添加至任务队列' return True,message
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
def configure_init(instance_id): ''' 修改配置时获取初始数据 :param instance_id: :return: ''' if not instance_id: logging.info('no instance id when get configure info') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误") resp = ConfigureInitInfoResp() ins_data = ins_s.InstanceService().get_instance_info(instance_id) host_ip = ins_s.get_hostip_of_instance(instance_id) if not ins_data or not host_ip: logging.info('instance %s data is no exist in db when get configure info', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) resp.c_instance_name = ins_data['name'] resp.c_app_info = ins_data['app_info'] resp.c_owner = ins_data['owner'] ins_status = ins_data['status'] if ins_status != VMStatus.STARTUP and ins_status != VMStatus.SHUTDOWN: logging.error('instance status %s is invalid when get instance configure init info', ins_status) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='只能在开机或关机状态下修改配置') if ins_data['create_source'] == '0': ins_images_data = ins_s.get_images_of_instance(instance_id) if ins_images_data: resp.c_system = ins_images_data[0]['system'] else: ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id) if ins_images_data: resp.c_system = ins_images_data['os_type'] """ ins_disks_data = ins_s.get_disks_of_instance(instance_id) if not ins_disks_data: logging.error('instance %s has no disk info when change instance configure', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 关机状态、windows系统都不能修改数据盘 if ins_status != VMStatus.SHUTDOWN and resp.c_system == 'linux': for _disk in ins_disks_data: _disk_info = { 'size_gb': _disk['size_gb'], 'mount_point': _disk['mount_point'] } resp.c_disk_gb_list.append(_disk_info) """ ins_flavor_data = ins_s.get_flavor_of_instance(instance_id) if not ins_flavor_data: logging.error('instance %s has no flavor info when change instance configure', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) resp.c_flavor_id = ins_flavor_data['flavor_id'] # flavor信息 flavors_nums, flavors_data = fla_s.FlavorService().get_all_flavors() for _flavor in flavors_data: # 系统盘容量不能修改 if _flavor['root_disk_gb'] == ins_flavor_data['root_disk_gb']: # 开机状态不能修改内存 if ins_status == VMStatus.STARTUP: if _flavor['memory_mb'] == ins_flavor_data['memory_mb']: _flavor_info = flavor_init_info.FlavorInitInfo().init_from_db(_flavor) resp.flavors.append(_flavor_info) else: _flavor_info = flavor_init_info.FlavorInitInfo().init_from_db(_flavor) resp.flavors.append(_flavor_info) ins_group_data = ins_s.get_group_of_instance(instance_id) if ins_group_data: resp.c_group_id = ins_group_data['group_id'] # user_group_ids_list = current_user_group_ids() # # 超级管理员组 # if 1 in user_group_ids_list: # is_super_group = True # else: # is_super_group = False # group信息 user_groups = current_user_groups() user_group_ids_list = [] is_super_group = False for _groups in user_groups: user_group_ids_list.append(_groups['id']) # 超级管理员组 if _groups['name'] == "supergroup": is_super_group = True # group信息 groups_params = { 'WHERE_AND': { '=': { 'dc_type': ins_group_data['dc_type'], 'isdeleted': '0' } }, } groups_nums, groups_data = group_s.GroupService().query_data(**groups_params) for _group in groups_data: # 管理员组的成员可以显示所有组,而非管理员组的只显示当前用户所在应用组 if not is_super_group and _group['id'] not in user_group_ids_list: continue _group_info = { 'group_id': _group['id'], 'group_name': _group['name'] } resp.groups.append(_group_info) # 连接libvirtd查询虚拟机网卡状态信息 _net_online = [] _net_offline = [] _libvirt_net_ret, _libvirt_net_info = vmManager.libvirt_get_netcard_state(host_ip, ins_data['name']) if _libvirt_net_ret != 0: _nic_status = False else: _nic_status = True for _p_libvirt_net_info in _libvirt_net_info: if _p_libvirt_net_info['state'] == NetCardStatus.UP: _net_online.append(_p_libvirt_net_info['mac']) else: _net_offline.append(_p_libvirt_net_info['mac']) # 虚拟机网卡信息返回前端 _db_net_card_data = ins_s.get_net_info_of_instance(instance_id) if _db_net_card_data: for _p_db_net_card_data in _db_net_card_data: if not _nic_status: _p_ins_nic_status = '' else: if _p_db_net_card_data['mac'] in _net_online: _p_ins_nic_status = '1' elif _p_db_net_card_data['mac'] in _net_offline: _p_ins_nic_status = '0' else: _p_ins_nic_status = '2' if not _p_db_net_card_data['segment_type']: _ip_type = '-1' else: _ip_type = _p_db_net_card_data['segment_type'] _i_net_info = { 'ip_addr': _p_db_net_card_data['ip_address'], 'vlan': _p_db_net_card_data['vlan'], 'mac_addr': _p_db_net_card_data['mac'], 'nic_status': _p_ins_nic_status, 'ip_type': _ip_type, 'nic_type': _p_db_net_card_data['nic_type'] } resp.c_net.append(_i_net_info) # 获取虚拟机所在网络区域下所有ip信息 resp.c_ips = [] ins_netarea_info = ins_s.get_netarea_of_instance(instance_id) ins_datacenter_info = ins_s.get_datacenter_of_instance(instance_id) if ins_datacenter_info and ins_datacenter_info['dc_type']: if ins_netarea_info and ins_netarea_info['id']: ip_segment_num, ip_segment_datas = ip_segment_s().get_segment_datas_in_net_area(ins_netarea_info['id']) if ip_segment_num > 0: # 获取可用ip ips_available = ip_service.get_all_available_ips(ip_segment_datas, ins_datacenter_info['dc_type']) if len(ips_available) > 0: ip_list = [] for ip_info in ips_available: ip_params = { "value": ip_info['ip_address'], "vlan": ip_info['vlan'], "ip_type": ip_info['ip_type'] } ip_list.append(ip_params) resp.c_ips = ip_list return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
def instance_configure(instance_id): ''' 虚机修改配置 规则: 热修改(开机状态):cpu disk 加 冷修改(关机状态):cpu mem 加减 disk 加 :param instance_id: :return: ''' n_flavor_id = request.values.get('flavor_id') n_app_info = request.values.get('app_info') n_owner = request.values.get('owner') n_group_id = request.values.get('group_id') n_net_conf_list_req = request.values.get('net_status_list') # start n_extend_list_req = request.values.get('extend_list') n_qemu_ga_update_req = request.values.get('qemu_ga_update') c_system = '' c_version = None # end if not instance_id or not n_flavor_id or not n_group_id: logging.error('params is invalid when change instance configure') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) ins_data = ins_s.InstanceService().get_instance_info(instance_id) ###################################add 2017/09/29#############################3 uuid = ins_data['uuid'] user_id = get_user()['user_id'] request_id = ins_s.generate_req_id() if not ins_data: logging.error('the instance %s is not exist in db when change instance configure', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # --------------------edit 2017/11/13----------------------- if ins_data['create_source'] == '0': ins_images_data = ins_s.get_images_of_instance(instance_id) if ins_images_data: c_system = ins_images_data[0]['system'] else: ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id) if ins_images_data: c_system = ins_images_data['os_type'] ins_status = ins_data['status'] # 获取虚拟机所在物理机信息 host_data = ins_s.get_host_of_instance(instance_id) ins_datacenter_info = ins_s.get_datacenter_of_instance(instance_id) if not host_data or not ins_datacenter_info: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法获取虚拟机所在物理机信息、机房信息") ins_data['dc_type'] = ins_datacenter_info['dc_type'] # 新flavor信息 n_flavor_data = fla_s.FlavorService().get_flavor_info(n_flavor_id) if not n_flavor_data: logging.error('flavor %s is invalid in db when change instance configure', n_flavor_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='新的配置数据有误,无法修改配置') # 虚机现有flavor信息 c_flavor_data = ins_s.get_flavor_of_instance(instance_id) if not c_flavor_data: logging.error('instance %s flavor is invalid in db when change instance configure', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) c_group_data = ins_s.get_group_of_instance(instance_id) if c_group_data and int(c_group_data['group_id']) != int(n_group_id): # 检查新应用组的配额 is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data) if not is_group_enough: logging.error('new group %s quota is not enough to change new flavor', n_group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg) params = {} if json_helper.loads(n_extend_list_req): # 检查当前应用组的配额 is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data, json_helper.loads(n_extend_list_req)) if not is_group_enough: logging.error('new group %s quota is not enough to change new flavor', n_group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg) # 检查物理机当前使用率情况是否满足扩容 is_host_available, ret_msg = __check_host_capacity(host_data, n_flavor_data, c_flavor_data , json_helper.loads(n_extend_list_req)) if not is_host_available: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_msg) vmname = ins_data['name'] uuid = '' host_ip = '' n_extend_list_req = json_helper.loads(n_extend_list_req) try: uuid = ins_data['uuid'] host_ip = ins_s.get_hostip_of_instance(instance_id) except: pass connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name']) if not connect_instance: pass # 添加扩容开始action ins_a_s.update_instance_status(VMStatus.CONFIGURE_ING, instance_id) ins_a_s.add_disk_extend_action_to_database(uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.START, 'start') # 满足扩容条件 if n_qemu_ga_update_req: if c_system.strip() == 'linux': flag, msg = connect_instance.exec_qemu_command( "cat /proc/self/mounts | grep -w / | grep -v rootfs | awk '{print $3}'") if not flag: c_version = None c_version = CentOS_Version.CentOS_6 if msg.strip() == 'ext4' else CentOS_Version.CentOS_7 flag, result = ins_a_s.extend_mount_size(n_extend_list_req, host_ip, vmname, uuid, c_version, instance_id) elif c_system.strip() == 'windows': flag, result = ins_a_s.extend_dev_size(n_extend_list_req, host_ip, vmname, uuid, instance_id) else: flag = False if flag: msg = "扩容成功" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.SUCCSESS, msg) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) else: msg = "扩容失败,{}".format(result) ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.FAILD, msg) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg=msg) else : # 非linux系统,关机状态,qemu-guest-agent没有更新成功 msg = "非linux系统,扩容失败" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.FAILD, msg) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg=msg) else: pass if c_flavor_data['vcpu'] != n_flavor_data['vcpu'] or c_flavor_data['memory_mb'] != n_flavor_data['memory_mb']: # 检查当前应用组的配额 is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data) if not is_group_enough: logging.error('new group %s quota is not enough to change new flavor', n_group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg) # 检查物理机当前使用率情况是否满足扩容 is_host_available, ret_msg = __check_host_capacity(host_data, n_flavor_data, c_flavor_data) if not is_host_available: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_msg) # 关机状态 if ins_status == VMStatus.SHUTDOWN: pass elif ins_status == VMStatus.STARTUP: # 开机状态 # cpu只能增 if c_flavor_data['vcpu'] > n_flavor_data['vcpu']: logging.error('vcpu only be increase in startup status, now vcpu %s > new vcpu %s', c_flavor_data['vcpu'], n_flavor_data['vcpu']) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='开机状态下,CPU数量只能增加不能减少') # 内存不能修改 if c_flavor_data['memory_mb'] != n_flavor_data['memory_mb']: logging.error('memory only no allow be change in startup status, now mem %s, new mem %s', c_flavor_data['memory_mb'], n_flavor_data['memory_mb']) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='开机状态下,不能修改内存容量') else: logging.error('instance status %s is invalid when change instance configure', ins_status) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='只能在开机或关机状态下修改配置') if n_flavor_data['vcpu'] == c_flavor_data['vcpu']: pass else: params['new_vcpu'] = n_flavor_data['vcpu'] params['old_vcpu'] = c_flavor_data['vcpu'] new_mem = n_flavor_data['memory_mb'] old_mem = c_flavor_data['memory_mb'] if new_mem == old_mem: pass else: # 检查内存是否超分 if not _check_mem_allocation(instance_id, new_mem, old_mem): logging.error('instance %s mem has over allocation, new mem %s, old mem %s', instance_id, new_mem, old_mem) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='物理内存不能超分') params['new_mem'] = new_mem params['old_mem'] = old_mem # 检查网络配置是否需要修改 n_net_conf_list = json_helper.loads(n_net_conf_list_req) if n_net_conf_list: params['net_status_list'] = n_net_conf_list # 没有一个指标可以修改 if not params: logging.error('vcpu, mem, disk no one can change when change instance configure') else: host_ip = ins_s.get_hostip_of_instance(ins_data['id']) if not host_ip: logging.error('instance %s has no host ip when change instance configure', ins_data['id']) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) ret_flavor = ins_a_s.change_instance_configure(host_ip, ins_data, c_flavor_data['flavor_id'], n_flavor_id, ins_status, **params) if not ret_flavor: ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) update_data_i = { 'app_info': n_app_info, 'owner': n_owner, 'updated_at': get_datetime_str() } where_data_i = { 'id': instance_id } ret_i = ins_s.InstanceService().update_instance_info(update_data_i, where_data_i) # if ret_i != 1: # logging.error('update instance info error when configure, update_data:%s, where_data:%s', # update_data_i, where_data_i) # return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) update_data_g = { 'group_id': n_group_id, 'updated_at': get_datetime_str() } where_data_g = { 'instance_id': instance_id } ret_g = ins_g_s.InstanceGroupService().update_instance_group_info(update_data_g, where_data_g) # if ret_g != 1: # logging.error('update group info error when configure, update_data:%s, where_data:%s', # update_data_g, where_data_g) # return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # if 'disk_gb_list' in params: # return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg='硬盘扩容任务发送成功') return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg='修改配置成功')
def v2v_op_init_info(): resp = V2v_0p_InitInfoResp() # area层级信息 - 总部 area_data = hostpool_service.get_level_info_hostpool_cs() for i in area_data: if not _filter_least_host_num(i['hostpool_id'], i['least_host_num']): continue resp.area.append(i) # flavor信息 flavors_nums, flavors_data = flavor_service.FlavorService( ).get_all_flavors() for i in flavors_data: _flavor_info = flavor_init_info.FlavorInitInfo().init_from_db(i) resp.flavors.append(_flavor_info) # segment信息 resp.segment = [] # {"env": "SIT", "seg": "10.202.26.0"}, # {"env": "SIT", "seg": "10.202.34.0"}, # {"env": "SIT", "seg": "10.202.50.0"}, # {"env": "SIT", "seg": "10.202.32.0"}, # {"env": "SIT", "seg": "10.202.84.0"}, # {"env": "SIT", "seg": "10.202.86.0"}, # {"env": "SIT", "seg": "10.202.42.0"}, # {"env": "SIT", "seg": "10.202.24.0"}, # {"env": "SIT", "seg": "10.202.44.0"}, # {"env": "SIT", "seg": "10.202.91.0"}, # {"env": "SIT", "seg": "10.202.16.0"}, # {"env": "SIT", "seg": "10.202.40.0"}, # {"env": "SIT", "seg": "10.202.98.0"}, # {"env": "SIT", "seg": "10.202.54.0"}, # {"env": "SIT", "seg": "10.202.38.0"}, # {"env": "SIT", "seg": "10.202.90.0"}, # {"env": "SIT", "seg": "10.202.52.0"}, # {"env": "SIT", "seg": "10.202.36.0"}, # {"env": "SIT", "seg": "10.202.94.0"}, # {"env": "SIT", "seg": "10.202.99.0"}, # {"env": "DEV", "seg": "10.202.10.0"}, # {"env": "DEV", "seg": "10.202.11.0"}, # {"env": "DEV", "seg": "10.202.12.0"}, # {"env": "DEV", "seg": "10.202.125.0"}, # {"env": "DEV", "seg": "10.202.23.0"}, # {"env": "DEV", "seg": "10.202.13.0"}, # {"env": "DEV", "seg": "10.202.14.0"}, # {"env": "DEV", "seg": "10.202.15.0"}, # {"env": "DEV", "seg": "10.202.4.0"}, # {"env": "DEV", "seg": "10.202.5.0"}, # {"env": "DEV", "seg": "10.202.6.0"}, # {"env": "DEV", "seg": "10.202.7.0"}, # {"env": "DEV", "seg": "10.202.8.0"}, # {"env": "DEV", "seg": "10.202.9.0"} # ] # group信息 groups_params = { 'WHERE_AND': { '=': { 'isdeleted': '0' } }, } groups_nums, groups_data = group_service.GroupService().query_data( **groups_params) for i in groups_data: _group_info = group_info.GroupInitInfo().init_from_db_1(i) resp.groups.append(_group_info) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
def task_check(): # 入参赋值 vmip = request.values.get('vm_ip') flavor_id = request.values.get('flavor_id') cloudarea = request.values.get('cloud_area') vm_ostype = request.values.get('vm_ostype') vm_segment = request.values.get('segment') # 入参完全性判断 if not vmip or not flavor_id or not cloudarea or not vm_ostype or not vm_segment: logging.info('params are invalid or missing') message = '入参缺失' return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg=message) else: # 获取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) message = '实例规格数据有误,无法进行v2v' return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg=message) # 获取对应openstack环境的管理节点及ssh账户信息 if cloudarea == "SIT": ctr_host = '10.202.83.12' ctr_pass = decrypt(OPENSTACK_SIT_PASS) elif cloudarea == "DEV": ctr_host = "10.202.123.4" ctr_pass = decrypt(OPENSTACK_DEV_PASS) else: message = 'openstack环境参数错误,无法进行v2v操作' return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) # 判断vm信息是否输入错误 vmexist = vm_exist(vmip, ctr_host, ctr_pass) if vmexist == False: message = '获取vm信息失败' return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) # 获取OS版本失败 osstat, verdata = get_vm_version(ctr_host, ctr_pass, vm_ostype, vmip) if osstat == False: message = '获取vmOS版本失败' return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) else: ver_data = verdata # 获取待迁移vm磁盘大小 vdiskdata = vm_disk_size(vmip, cloudarea, ctr_host, ctr_pass) if vdiskdata == False: message = '获取vm磁盘信息失败' return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) vdisk = vdiskdata data_disk = vdisk - 80 # 判断待转化vm是否关机 vmshutdown = vm_stat(vmip, ctr_host, ctr_pass) if vmshutdown == False: message = '待转化vm未关机' 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: message = '网段信息有误,无法进行v2v' return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) else: ip_data = ip_s.IPService().get_ip_info_by_ipaddress(vmip) if ip_data: ip_data_status = ip_data['status'] if ip_data_status != '0': message = "IP与现有环境冲突,无法进行v2v" return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=message) return_info = {'vm_osver': ver_data, 'vm_disk': str(data_disk)} message = "获取VM信息成功" return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg=message, data=return_info)
def v2v_openstack_intodb(hostpool_id): ''' v2v_openstack :param hostpool_id: :return: ''' # 判断是否为重试操作 retry = request.values.get('retry') # 如果非重试进行以下步骤 if retry != '1': # 入参赋值 vmname = request.values.get('vm_name').strip() vmip = request.values.get('vm_ip').strip() flavor_id = request.values.get('flavor_id').strip() cloudarea = request.values.get('cloud_area').strip() vm_ostype = request.values.get('vm_ostype').strip() vm_app_info = request.values.get('vm_app_info').strip() vm_owner = request.values.get('vm_owner').strip() vm_group_id = request.values.get('group_id').strip() user_id = request.values.get('user_id').strip() vm_segment = request.values.get('segment').strip() # 入参完全性判断 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') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg='入参缺失') else: # 获取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'] # 获取对应openstack环境的管理节点及ssh账户信息 if cloudarea == "SIT": ctr_host = '10.202.83.12' ctr_pass = decrypt(OPENSTACK_SIT_PASS) elif cloudarea == "DEV": ctr_host = "10.202.123.4" ctr_pass = decrypt(OPENSTACK_DEV_PASS) else: return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg='openstack环境参数错误,无法进行v2v操作') #判断vm信息是否输入错误 vmexist = vm_exist(vmip, ctr_host, ctr_pass) if vmexist == False: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='获取vm信息失败') #获取OS版本失败 osstat, verdata = get_vm_version(ctr_host, ctr_pass, vm_ostype, vmip) if osstat == False: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='获取vmOS版本失败') else: ver_data = verdata # 获取待迁移vm磁盘大小 vdiskdata = vm_disk_size(vmip, cloudarea, ctr_host, ctr_pass) if vdiskdata == False: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='获取vm磁盘信息失败') vdisk = vdiskdata data_disk = vdisk - 80 # 判断待转化vm是否关机 vmshutdown = vm_stat(vmip, ctr_host, ctr_pass) if vmshutdown == False: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='待转化vm未关机') # 获取可用目标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() # 信息入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, ver_data) if instance_info < 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='信息入库失败') # 将步骤信息存入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) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='信息入库失败') # 将目标kvmhost存入信息表 v2v_op.update_v2v_desthost(request_Id, host) v2v_op.update_v2v_step(request_Id, v2vActions.BEGIN) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg=message)
def instance_init_info(): 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 def _filter_no_segment_info(hostpool_id): ''' 过滤掉没有网段信息的集群 :param hostpool_id: :return: ''' segments_list = hostpool_service.get_segment_info(hostpool_id) if not segments_list: logging.error('filter hostpool %s that has no segment info when get create init info', hostpool_id) return False return True resp = InstanceInitInfoResp() user_all_area_ids = current_user_all_area_ids() # area层级信息 - 总部 area_zb_data = hostpool_service.get_level_info_hostpool_zb() for i in area_zb_data: # 不显示不满足最少host数的集群 if not _filter_least_host_num(i['hostpool_id'], i['least_host_num']): continue # 不显示没有网段信息的集群 if not _filter_no_segment_info(i['hostpool_id']): continue # 只显示当前用户所属的区域 if user_all_area_ids and i['area_id'] not in user_all_area_ids: continue resp.area_ZB.append(i) # area层级信息 - 地区 area_dq_data = hostpool_service.get_level_info_hostpool_dq() for i in area_dq_data: # 不显示不满足最少host数的集群 if not _filter_least_host_num(i['hostpool_id'], i['least_host_num']): continue # 不显示没有网段信息的集群 if not _filter_no_segment_info(i['hostpool_id']): continue # 只显示当前用户所属的区域 if user_all_area_ids and i['area_id'] not in user_all_area_ids: continue _area_dq_info = area_dq_init_info.AreaDQInitInfo().init_from_db(i) # 表示有父区域 if i['parent_id']: _parent_info = area_service.AreaService().get_area_info(i['parent_id']) if _parent_info: _area_dq_info.area_name = _parent_info['displayname'] _area_dq_info.child_area_name = i['area_name'] else: # 有父区域ID但没有相应信息,则当做没有父区域 _area_dq_info.area_name = i['area_name'] else: _area_dq_info.area_name = i['area_name'] resp.area_DQ.append(_area_dq_info) # flavor信息 flavors_nums, flavors_data = flavor_service.FlavorService().get_all_flavors() for i in flavors_data: _flavor_info = flavor_init_info.FlavorInitInfo().init_from_db(i) resp.flavors.append(_flavor_info) # image信息 - windows images_windows_nums, images_windows_data = image_service.ImageService().get_all_images('windows') for i in images_windows_data: _image_windows_info = image_init_info.ImageInitInfo().init_from_db(i) resp.images_windows.append(_image_windows_info) # image信息 - linux images_linux_nums, images_linux_data = image_service.ImageService().get_all_images('linux') for i in images_linux_data: _image_linux_info = image_init_info.ImageInitInfo().init_from_db(i) resp.images_linux.append(_image_linux_info) # group信息 user_groups = current_user_groups() user_group_ids_list = [] is_super_group = False for _groups in user_groups: user_group_ids_list.append(_groups['id']) # 超级管理员组 if _groups['name'] == "supergroup": is_super_group = True groups_params = { 'WHERE_AND': { '=': { 'isdeleted': '0' } }, } groups_nums, groups_data = group_service.GroupService().query_data(**groups_params) for i in groups_data: # 管理员组的成员可以显示所有组,而非管理员组的只显示当前用户所在应用组 if not is_super_group and i['id'] not in user_group_ids_list: continue _group_info = group_info.GroupInitInfo().init_from_db_1(i) resp.groups.append(_group_info) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
def instance_create_from_other_platform_with_ip(): ''' 外部平台虚拟机创建 :return: ''' _init_log('instanc_create_request_from_other_platform') data_from_other_platform = request.data logging.info(data_from_other_platform) data_requset = json_helper.loads(data_from_other_platform) image_name = data_requset['image'] vcpu = data_requset['vcpu'] mem_mb = data_requset['mem_MB'] disk_gb = data_requset['disk_GB'] count = data_requset['count'] sys_code = data_requset['sys_code'] opuser = data_requset['opUser'] taskid_vs = data_requset['taskid'] req_env = data_requset['env'] req_net_area = data_requset['net_area'] req_datacenter = data_requset['datacenter'] task_id_kvm = ins_s.generate_task_id() sys_opr_name = data_requset['Op_Main_Engineer_Primary'] sys_opr_id = data_requset['Op_Main_Engineer_Prim'] cluster_id = data_requset['cluster_id'] vip_needed = data_requset['vip_needed'] # 是否需要vip,0为不需要,1需要 vm_ip_info = data_requset['vm_info'] vip_info = data_requset['vip_info'] api_origin = data_requset[ 'apiOrigin'] # api名称,维石为vishnu, 软负载为sfslb, 其他的需要定义 # 前端暂时不是传虚拟机root密码过来 password = None app_info = data_requset['application_info'] # hostpool_id = int(data_requset['hostpool_id']) # 特殊类型应用,返回集群id hostpool_id = '' logging.info('task %s : check params start when create instance', task_id_kvm) if not taskid_vs or not api_origin: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of taskid or api_origin when create ' 'instance') # 判断工单是否为失败重做 check_job_data = { 'WHERE_AND': { '=': { 'taskid_api': taskid_vs }, }, } ret_job_num, ret_job_data = request_r_s.RequestRecordService( ).request_db_query_data(**check_job_data) if ret_job_num == 1: for _job_data in ret_job_data: if _job_data['task_status'] == '0': return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='task is now doing, wait a moment, ' 'do not repeat create') elif _job_data['task_status'] == '1': # 将request_record数据库表中“task_status”、“response_to_api”重置为0重启任务 update_db_time = get_datetime_str() _update_data = { 'task_status': '0', 'response_to_api': '0', 'finish_time': update_db_time, 'request_status_collect_time': update_db_time, } _where_data = { 'taskid_api': taskid_vs, } ret = request_r_s.RequestRecordService().update_request_status( _update_data, _where_data) if ret <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='update request status failed, ' 'please call kvm system manager ' 'or retry create again') return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.SUCCEED, detail='start to recreate vm') elif _job_data['task_status'] == '2': threads = [] # 将request_record数据库表中“task_status”、“response_to_api”重置为0重启任务 update_db_time = get_datetime_str() _update_data = { 'task_status': '0', 'response_to_api': '0', 'finish_time': update_db_time, 'request_status_collect_time': update_db_time, } _where_data = { 'taskid_api': taskid_vs, } ret = request_r_s.RequestRecordService().update_request_status( _update_data, _where_data) if ret <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='update request status failed, ' 'please call kvm system manager ' 'or retry create again') # 找到工单对应的虚拟机,发送task_id、request_id到kafka重新创建 ins_params = { 'WHERE_AND': { "=": { 'task_id': _job_data['taskid_kvm'], 'isdeleted': '0', 'status': '100' } }, } ins_num, ins_data = ins_s.InstanceService().query_data( **ins_params) if ins_num > 0: for per_ins_data in ins_data: kafka_send_thread = threading.Thread( target=instance_msg_send_to_kafka, args=( per_ins_data['task_id'], per_ins_data['request_id'], )) threads.append(kafka_send_thread) kafka_send_thread.start() # 判断多线程是否结束 for t in threads: t.join() return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.SUCCEED, detail='start to recreate vm') if api_origin == ApiOriginString.VISHNU: api_origin = ApiOrigin.VISHNU elif api_origin == ApiOriginString.SFSLB: api_origin = ApiOrigin.SFSLB elif api_origin == ApiOriginString.FWAF: api_origin = ApiOrigin.FWAF else: api_origin = ApiOrigin.VISHNU if vip_needed == '1' and len(vip_info) <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of vip datas when create instance') # 校验前端vip是否存在数据库中且ip为预保留状态 if vip_needed == '1': vip_available = 0 vip_info_list = [] for per_vip in vip_info: per_vip_info = ip_service.IPService().get_ip_by_ip_address( per_vip['ip']) if per_vip_info and per_vip_info[ 'status'] == IPStatus.PRE_ALLOCATION: vip_info_list.append(per_vip_info) vip_available += 1 if vip_available != len(vip_info): return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='vip nums from vishnu not equal apply vip nums ' 'when create instance') # 校验前端ip是否存在数据库中且ip为预保留状态 ip_available = 0 ip_info_list = [] for per_ip in vm_ip_info: per_ip_info = ip_service.IPService().get_ip_by_ip_address(per_ip['ip']) if per_ip_info and per_ip_info['status'] == IPStatus.PRE_ALLOCATION: ip_info_list.append(per_ip_info) ip_available += 1 if ip_available != int(count): return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='vm ip nums from vishnu not equal apply vm nums ' 'when create instance') # 获取ip对应的网段信息 segment_info = segment_service.SegmentService().get_segment_info( ip_info_list[0]['segment_id']) if not segment_info: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='can not find segment infomation for ip ' 'when create instance') # 根据维石平台输入的虚拟机cpu、内存选择模板 if not vcpu or not mem_mb: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of vcpu or mem_MB when create instance') flavor_query = flavor_service.get_flavor_by_vcpu_and_memory(vcpu, mem_mb) if not flavor_query: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='can not get flavor information when create instance') flavor_id = flavor_query['id'] # 根据维石平台输入的环境、网络区域查找对应的物理集群 if not req_env or not req_net_area: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of req_net_area or req_env ' 'when create instance') if not hostpool_id: hostpool_query = hostpool_service.get_hostpool_info_by_name( str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), req_datacenter, req_net_area) if not hostpool_query: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='can not get host_pool information ' 'when create instance') hostpool_id = hostpool_query['hostpool_id'] # 根据维石平台输入的系统运维人员工号维护对应应用组信息 if not sys_opr_id or not cluster_id: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of sys_opr_name, sys_opr_id ' 'or cluster_id when create instance') ret_group, group_id = _user_group_check( str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), sys_code, sys_opr_name, sys_opr_id, cluster_id) if not ret_group: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail=group_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('task %s : params are invalid when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of image_name, disk_gb ' 'or count when create instance') if int(count) > int(INSTANCE_MAX_CREATE): logging.error( 'task %s : create count %s > max num %s when create instance', task_id_kvm, count, INSTANCE_MAX_CREATE) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='批量创建最大实例数不能超过32个') logging.info('task %s : check params successful when create instance', task_id_kvm) # 数据盘最少50GB # 这里只是一个数据盘,后面有多个数据盘 vm_disk_gb = int(disk_gb) if int(disk_gb) > DATA_DISK_GB else DATA_DISK_GB # 获取主机列表(不包括锁定、维护状态) logging.info( 'task %s : get all hosts in hostpool %s start when create instance', task_id_kvm, 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( 'task %s : available host resource not enough when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='集群不够资源,无法创建实例') logging.info( 'task %s : get all hosts in hostpool %s successful, all hosts nums %s when create instance', task_id_kvm, hostpool_id, all_hosts_nums) # 过滤host logging.info('task %s : filter hosts start when create instance', task_id_kvm) 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('task %s : no available host when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='没有适合的主机,无法创建实例') logging.info('task %s : filter hosts successful when create instance', task_id_kvm) logging.info('task %s : get need info start when create instance', task_id_kvm) # 获取flavor信息 flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id) if not flavor_info: logging.error( 'task %s : flavor %s info not in db when create instance', task_id_kvm, flavor_id) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='实例规格数据有误,无法创建实例') # VM分配给HOST logging.info('task %s : match hosts start when create instance', task_id_kvm) 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( 'task %s : match host resource not enough when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='没有适合的主机,无法创建实例') logging.info('task %s : match hosts successful when create instance', task_id_kvm) # 获取hostpool的net area信息 hostpool_info = hostpool_service.HostPoolService().get_hostpool_info( hostpool_id) if not hostpool_info: logging.error( 'task %s : hostpool %s info not in db when create instance', task_id_kvm, hostpool_id) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='物理机池所属网络区域信息有误,无法创建实例') net_area_id = hostpool_info['net_area_id'] logging.info('task %s : get need info successful when create instance', task_id_kvm) # 组配额控制 logging.info('task %s : check group quota start when create instance', task_id_kvm) is_quota_enough, quota_msg = check_group_quota(group_id, flavor_info, vm_disk_gb, count) if not is_quota_enough: logging.error( 'task %s : group %s is no enough quota when create instance', task_id_kvm, group_id) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='资源组配额不足,无法创建实例') logging.info('task %s : check group quota successful when create instance', task_id_kvm) ips_list = ip_info_list segment_data = segment_info logging.info('task %s : check ip resource start when create instance', task_id_kvm) logging.info('task %s : get need 1 info start when create instance', task_id_kvm) # 获取镜像信息,一个image_name可能对应多个id image_nums, image_data = image_service.ImageService().get_images_by_name( image_name) if image_nums <= 0: logging.info('task %s : no image %s info in db when create instance', task_id_kvm, image_name) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='没有镜像资源,无法创建实例') # 获取集群所在的环境 vm_env = hostpool_service.get_env_of_hostpool(hostpool_id) # hostpool对应的机房名 dc_name = hostpool_service.get_dc_name_of_hostpool(hostpool_id) # 实例操作系统 instance_system = image_data[0]['system'] logging.info('task %s : get need 1 info successful when create instance', task_id_kvm) # 获取虚机名资源 logging.info( 'task %s : check instance name resource start when create instance', task_id_kvm) is_name_enough, instance_name_list = _check_instance_name_resource( vm_env, dc_name, instance_system, count) if not is_name_enough: logging.error( 'task %s : datacenter %s has no enough instance name resource', task_id_kvm, dc_name) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='主机名资源不足,无法创建实例') logging.info( 'task %s : check instance name resource successful when create instance', task_id_kvm) # 如果需要vip,分配第‘count + 1’个同时记录vip_info表格 if vip_needed == '1': for per_avalible_vip in vip_info_list: # 标记ip已使用 update_vip_data = {'status': IPStatus.USED} where_vip_data = {'id': per_avalible_vip['id']} ret_mark_ip = ip_service.IPService().update_ip_info( update_vip_data, where_vip_data) if ret_mark_ip <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail="标记ip为已使用状态失败,请重新申请") # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': per_avalible_vip['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail="录入ip信息失败,请联系系统管理员") # 挂载点 if instance_system == 'linux': mount_point = '/app' else: mount_point = 'E' logging.info('task %s : create thread start when create instance', task_id_kvm) 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_kvm, instance_name, app_info, sys_opr_id, 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, cluster_id), name='thread-instance-create-' + task_id_kvm) all_threads.append(create_ins_t) create_ins_t.start() for thread in all_threads: thread.join() logging.info('task %s : create thread successful when create instance', task_id_kvm) # 录入外应用的taskid到工单表格中 time_now_for_insert_request_to_db = get_datetime_str() request_info_data = { "taskid_api": taskid_vs, "api_origin": api_origin, "taskid_kvm": task_id_kvm, "vm_count": count, "user_id": opuser, "start_time": time_now_for_insert_request_to_db, "task_status": "0", # 代表任务执行中 "response_to_api": "0", "istraceing": "0", "request_status_collect_time": time_now_for_insert_request_to_db } request_record_db_ret = request_r_s.RequestRecordService( ).add_request_record_info(request_info_data) if request_record_db_ret.get('row_num') <= 0: logging.error( 'task %s : can not add request record information to db when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='录入工单信息到数据库失败') return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.SUCCEED, detail='start to create vm')
def esx_do_task(): # 获取当前在进行的任务清单 list_working = v2v_op.get_v2v_todo() if not list_working: time.sleep(60) return 0 for i in list_working: # 获取当前任务信息 request_id = i['request_id'] vm_ip = i['vm_ip'] vm_name = i['vm_name'] vm_vlan = i['vmvlan'] flavor_id = i['flavor_id'] cloud_area = i['cloud_area'] vm_mac = i['vm_mac'] vm_uuid = i['vm_uuid'] step_done = i['step_done'] dest_host = i['dest_host'] status = i['status'] ostype = i['vm_ostype'] dest_dir = i['dest_dir'] on_task = i['on_task'] source = i['source'] esx_ip = i['esx_ip'] esx_passwd = i['esx_passwd'] vmware_vm = i['vmware_vm'] if status == 0 and on_task == '0' and source == VMCreateSource.ESX: # 获取flavor信息 flavor_info = flavor_service.FlavorService().get_flavor_info( flavor_id) vmcpu = str(flavor_info['vcpu']) vmmem = flavor_info['memory_mb'] # 创建目标文件夹 esx_v2v_sta1 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta1 == True: step_done1 = v2v_op.get_v2v_step(request_id) if step_done1 == esx_v2vActions.BEGIN: threadlock = threading.Lock() threadlock.acquire() v2v_op.updata_v2v_ontask(request_id, '1') threadlock.release() # 在目标服务器上创建文件夹 createdir(dest_host, request_id, "command", dest_dir) # 创建存储池 esx_v2v_sta2 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta2 == True: step_done2 = v2v_op.get_v2v_step(request_id) if step_done2 == esx_v2vActions.CREATE_DEST_DIR: threadlock = threading.Lock() threadlock.acquire() v2v_op.updata_v2v_ontask(request_id, '1') threadlock.release() # 创建存储池 host_ip = dest_host dir = v2v_op.get_v2v_destdir(request_id) dir_uuid = dir.replace('/app/image/', '') _create_storage_pool(host_ip, dir_uuid, request_id) # 拷贝vm文件至目标host esx_v2v_sta3 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta3 == True: # 获取任务 step_done3 = v2v_op.get_v2v_step(request_id) if step_done3 == esx_v2vActions.CREATE_STOR_POOL: threadlock = threading.Lock() threadlock.acquire() v2v_op.updata_v2v_ontask(request_id, '1') threadlock.release() # 将vm磁盘文件拷贝至kvmhost本地 virt_v2v_copy_to_local(dest_dir, dest_host, esx_ip, esx_passwd, vmware_vm, request_id) # v2v拷贝后的vm文件 esx_v2v_sta4 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta4 == True: step_done4 = v2v_op.get_v2v_step(request_id) if step_done4 == esx_v2vActions.COPY_FILE_TO_LOCAL: threadlock = threading.Lock() threadlock.acquire() v2v_op.updata_v2v_ontask(request_id, '1') threadlock.release() # 将获取到的vm文件v2v virt_v2v(dest_dir, dest_host, request_id, vmware_vm) # 删除v2v过程中的临时文件 esx_v2v_sta5 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta5 == True: step_done5 = v2v_op.get_v2v_step(request_id) if step_done5 == esx_v2vActions.VIRT_V2V_FILES: v2v_op.updata_v2v_ontask(request_id, '1') # 删除v2v过程中的临时文件 rmrawfile(dest_host, vmware_vm, request_id) # vm系统盘标准化 esx_v2v_sta6 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta6 == True: step_done6 = v2v_op.get_v2v_step(request_id) if step_done6 == esx_v2vActions.DELETE_TMP_FILE: v2v_op.updata_v2v_ontask(request_id, '1') # vm系统盘标准化 ch_sys_disk_name(dest_dir, dest_host, vmware_vm, vm_name, request_id) # vm数据盘标准化 esx_v2v_sta7 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta7 == True: step_done7 = v2v_op.get_v2v_step(request_id) if step_done7 == esx_v2vActions.VM_SYS_DISK_STD: v2v_op.updata_v2v_ontask(request_id, '1') vm_data_disk_std(dest_dir, dest_host, vm_name, request_id, vmware_vm) # vm注册 esx_v2v_sta8 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta8 == True: step_done8 = v2v_op.get_v2v_step(request_id) if step_done8 == esx_v2vActions.VM_DATA_DISK_STD: v2v_op.updata_v2v_ontask(request_id, '1') vmlistdata = v2v_op.v2vTaskService( ).get_v2v_task_by_requestid(request_id)['volumelist'] volumes_d = [] vmsysdisk = dest_dir + '/' + vm_name + '.img' volumes_d.append(vmsysdisk) if int(vmlistdata) > 0: tag = 1 while tag <= int(vmlistdata): vmdatadisk = dest_dir + '/' + vm_name + '_disk' + str( tag) tag = tag + 1 volumes_d.append(vmdatadisk) print volumes_d vm_define(request_id, ostype, dest_host, vm_name, vmmem, vmcpu, vm_uuid, volumes_d, vm_vlan, vm_mac) # vm开机1 esx_v2v_sta9 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta9 == True: step_done9 = v2v_op.get_v2v_step(request_id) if step_done9 == esx_v2vActions.VM_DEFINE1: v2v_op.updata_v2v_ontask(request_id, '1') vm_start1(dest_host, vm_name, request_id, 'shell', ostype) # 添加临时盘 esx_v2v_sta10 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta10 == True: step_done10 = v2v_op.get_v2v_step(request_id) if step_done10 == esx_v2vActions.VM_START1: v2v_op.updata_v2v_ontask(request_id, '1') v2v_esx_disk_attach_static(vm_name, dest_host, request_id) #win vm磁盘格式修改 esx_v2v_sta12 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta12 == True: step_done12 = v2v_op.get_v2v_step(request_id) if step_done12 == esx_v2vActions.ATTACH_DISK: v2v_op.updata_v2v_ontask(request_id, '1') win_disk_ch(vm_name, dest_host, request_id) #vm 开机2 esx_v2v_sta13 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta13 == True: step_done13 = v2v_op.get_v2v_step(request_id) if step_done13 == esx_v2vActions.WINDOWS_DISK_CH: v2v_op.updata_v2v_ontask(request_id, '1') vm_start2(dest_host, vm_name, request_id, 'shell', vm_uuid) # win vm 标准化 esx_v2v_sta11 = v2v_op.get_v2v_running_by_reqid(request_id) if esx_v2v_sta11 == True: step_done11 = v2v_op.get_v2v_step(request_id) if step_done11 == esx_v2vActions.VM_START2: v2v_op.updata_v2v_ontask(request_id, '1') win_vm_std(request_id)