def instance_msg_send_to_kafka(task_id, request_id): ''' 通过传入的task_id, request_id拼凑消息发送kafka,可供外部接口调用 :param request_id: :return: ''' _ins_info = ins_s.InstanceService().get_instance_info_by_requestid(request_id) if not _ins_info: return logging.error('task %s : can not find instance info ' 'when retry create instance send kafka msg', task_id) if _ins_info['isdeleted'] == '1': return logging.error('task %s : instance has been deleted ' 'when retry create instance send kafka msg', task_id) _ins_host_ip = ins_s.get_hostip_of_instance(_ins_info['id']) _ins_hostpool_db_info = ins_s.get_hostpool_of_instance(_ins_info['id']) _ins_flavor_db_info = ins_s.get_flavor_of_instance(_ins_info['id']) if not _ins_host_ip or not _ins_hostpool_db_info or not _ins_flavor_db_info: return logging.error('task %s : instance host, hostpool or flavor information' 'when retry create instance send kafka msg', task_id) # 获取虚拟机数据盘大小 ret_disk_status, vm_disk_gb = ins_s.get_data_disk_size_of_instance(_ins_info['id']) if not ret_disk_status: return logging.error('task %s : instance data disk size can not find' 'when retry create instance send kafka msg', task_id) # 获取虚拟机对应网段信息 segment_data = ins_s.get_net_segment_info_of_instance(_ins_info['id']) if not segment_data: return logging.error('task %s : instance segment information can not find' 'when retry create instance send kafka msg', task_id) # 获取虚拟机所在机房类型 vm_env = hostpool_service.get_env_of_hostpool(_ins_hostpool_db_info['id']) if not vm_env: return logging.error('task %s : instance env information can not find' 'when retry create instance send kafka msg', task_id) ins_images = ins_s.get_images_of_instance(_ins_info['id']) if not ins_images: return logging.error('task %s : instance image information can not find' 'when retry create instance send kafka msg', task_id) else: instance_system = ins_images[0]['system'] image_name = ins_images[0]['name'] # 获取镜像信息,一个image_name可能对应多个id image_nums, image_data = image_service.ImageService().get_images_by_name(image_name) if image_nums <= 0: return logging.error('task %s : instance image information can not find' 'when retry create instance send kafka msg', task_id) # 拼装消息需要的镜像信息 image_list = [] # 数据盘数量 data_image_num = 0 for _image in image_data: _image_type = _image['type'] _info = { "disk_format": _image['format'], "url": _image['url'], "image_size_gb": _image['size_gb'] # 镜像预分配大小 } # 系统盘 if _image_type == ImageType.SYSTEMDISK: _disk_name = _ins_info['name'] + '.img' _info['image_dir_path'] = '/app/image/' + _ins_info['uuid'] + '/' + _disk_name _info['disk_name'] = _disk_name _info['disk_size_gb'] = None _info['dev_name'] = 'vda' else: # 数据盘 _disk_name = _ins_info['name'] + '.disk' + str(data_image_num + 1) _disk_dev_name = _get_vd_map(data_image_num) _info['image_dir_path'] = '/app/image/' + _ins_info['uuid'] + '/' + _disk_name _info['disk_name'] = _disk_name _info['disk_size_gb'] = int(vm_disk_gb) _info['dev_name'] = _disk_dev_name data_image_num += 1 image_list.append(_info) # 发送异步消息到队列 data = { "routing_key": "INSTANCE.CREATE", "send_time": get_datetime_str(), "data": { "task_id": task_id, "request_id": request_id, "host_ip": _ins_host_ip, "uuid": _ins_info['uuid'], "hostname": _ins_info['name'], # 实例名 "memory_mb": _ins_flavor_db_info['memory_mb'], "vcpu": _ins_flavor_db_info['vcpu'], "ostype": instance_system, "user_id": _ins_info['owner'], "disks": image_list, "disk_size": int(vm_disk_gb), "image_name": image_name, "net_area_id": segment_data['net_area_id'], "networks": [ { "net_card_name": "br_bond0." + segment_data['vlan'], "ip": segment_data['ip_address'], "netmask": segment_data['netmask'], "dns1": segment_data['dns1'], "dns2": segment_data['dns2'], "mac": segment_data['mac'], "gateway": segment_data['gateway_ip'], "env": vm_env # SIT STG PRD DR } ] } } ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data) # 修改虚拟机状态为创建中 update_data = { 'status': VMStatus.CREATING, 'created_at': get_datetime_str(), 'updated_at': get_datetime_str() } where_data = { 'uuid': _ins_info['uuid'] } ins_s.InstanceService().update_instance_info(update_data, where_data) return 'all done'
def console(): """ 虚拟机vnc控制台 :param instance_id: :return : """ """ if not instance_id: logging.info('no instance id when get configure info') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误") ins_data = ins_s.InstanceService().get_instance_info(instance_id) host_ip = ins_s.get_hostip_of_instance(instance_id) if not ins_data or not host_ip: logging.info('instance %s data is no exist in db when get configure info', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) instance_name = ins_data['name'] connect_disk_device_get = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=instance_name) # result, data = vmManager.libvirt_get_vnc_port(connect_disk_device_get, instance_name) # if not result: # logging.info(data) # return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) """ console_server_host = request.host.split(':')[0] apple = request.query_string.decode().strip() peeledapple = apple.split('=') instance_uuid = peeledapple[1] if not instance_uuid or not console_server_host: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) ins_info = InstanceService().get_instance_info_by_uuid(instance_uuid) if not ins_info: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) kvm_host_ip = get_hostip_of_instance(ins_info['id']) if not kvm_host_ip: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) # 连接libvirtd查询虚拟机console端口号 connect_instance = vmManager.libvirt_get_connect(kvm_host_ip, conn_type='instance', vmname=ins_info['name']) status, vnc_port = vmManager.libvirt_get_vnc_console( connect_instance, ins_info['name']) if not status: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) token = str(kvm_host_ip) + '-' + str(vnc_port) resp = make_response( render_template('console-vnc.html', vm_name=ins_info['name'], ws_host=console_server_host, ws_port=6080)) resp.set_cookie('token', token) # 添加操作记录: try.. except .. 部分 try: user = user_service.get_user() extra_data = "name:" + ins_info['name'] + "," + "uuid:" + peeledapple[1] add_operation_other(user["user_id"], OperationObject.VM, OperationAction.CONSOLE, "SUCCESS", extra_data) except: pass return resp
def instance_disk_config(msg_data): logging.info("--" * 25) logging.info(msg_data) msg = json_helper.read(msg_data) data = msg.get('data') user_id = data.get('user_id') request_id = data.get('request_id') instance_id = data.get('instance_id') vm_uuid = data.get('uuid') disks = data.get('disk_msg') if request_id is None or instance_id is None: return 1 instance_info = InstanceService().get_instance_info(instance_id) for disk in disks: # 查看虚拟机mount所在磁盘位置、磁盘当前大小,vg、lv名称 host_ip = get_hostip_of_instance(instance_id) mount_point = disk['mount_point'] if mount_point and host_ip and instance_info['name']: vm_name = instance_info['name'] status, disk_path, disk_size, vm_vg_lv, _message = _check_volume_is_existed_and_volume_size( host_ip, vm_uuid, vm_name, mount_point, request_id, user_id) if status: if disk['size_gb'] <= disk_size: logging.info('disk size user input less than now, failed') else: add_instance_actions(vm_uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_RESIZE, 'start') connect_disk_resize = vmManager.libvirt_get_connect( host_ip, conn_type='instance', vmname=vm_name) disk_resize_status, disk_resize_msg = vmManager.libvirt_config_disk_resize( connect_disk_resize, disk_path, int(disk['size_gb'])) logging.info(disk_resize_msg) if disk_resize_status: instance_disk_resize_status = ActionStatus.SUCCSESS _message = 'instance %s disk %s resize successful' % ( vm_name, disk_path) update_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_RESIZE, instance_disk_resize_status, _message) print 'start to get disk dev:' add_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_DEVICE, 'start') connect_disk_device_get = vmManager.libvirt_get_connect( host_ip, conn_type='instance', vmname=vm_name) disk_device_status, disk_dev = vmManager.libvirt_get_disk_device_by_path( connect_disk_device_get, disk_path) logging.info('disk device is: ' + disk_dev) if disk_device_status: instance_disk_device_status = ActionStatus.SUCCSESS _message = 'instance %s disk device get successful, device name is %s' % ( vm_name, disk_dev) update_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_DEVICE, instance_disk_device_status, _message) # 查看虚拟机状态 add_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_STATUS_CHECK, 'start') print 'start to check instance %s status' % instance_id instance_info = InstanceService( ).get_instance_info(instance_id) if instance_info['status'] == '3': instance_status = ActionStatus.SUCCSESS _message = 'instance %s is running' % vm_name update_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_STATUS_CHECK, instance_status, _message) add_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_INJECT_TO_OS, 'start') # 下发qemu agent命令 connect_disk_inject = vmManager.libvirt_get_connect( host_ip, conn_type='instance', vmname=vm_name) disk_add_size = str( int(disk['size_gb']) - int(disk_size) - 1) inject_disk_stauts, result_msg = vmManager.libvirt_inject_resize_disk( connect_disk_inject, disk_dev, vm_vg_lv, disk_add_size) logging.info(result_msg) if inject_disk_stauts: instance_disk_inject_on_os_status = ActionStatus.SUCCSESS _message = 'instance %s disk resize on os successful' % vm_name update_instance_actions( vm_uuid, request_id, user_id, InstaceActions. INSTANCE_DISK_INJECT_TO_OS, instance_disk_inject_on_os_status, _message) # 修改数据库虚拟机磁盘大小 update_data = { 'size_gb': disk['size_gb'], 'updated_at': get_datetime_str() } where_data = { 'instance_id': instance_id, 'mount_point': mount_point } ret = ins_d_s.InstanceDiskService( ).update_instance_disk_info( update_data, where_data) else: instance_disk_inject_on_os_status = ActionStatus.FAILD _message = 'instance %s disk resize on os failed because %s' % ( vm_name, result_msg) update_instance_actions( vm_uuid, request_id, user_id, InstaceActions. INSTANCE_DISK_INJECT_TO_OS, instance_disk_inject_on_os_status, _message) else: instance_status = ActionStatus.FAILD _message = 'failed: instance %s not running' % vm_name update_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_STATUS_CHECK, instance_status, _message) else: instance_disk_device_status = ActionStatus.FAILD _message = 'instance %s disk device get failed' % vm_name update_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_DEVICE, instance_disk_device_status, _message) else: instance_disk_resize_status = ActionStatus.FAILD _message = 'instance %s disk %s resize faile because %s' % ( vm_name, disk_path, disk_resize_msg) update_instance_actions( vm_uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_RESIZE, instance_disk_resize_status, _message) else: logging.info(_message) return 'all job done, check whether has error in database instance'
def instance_msg_send_to_kafka(task_id, request_id): ''' 通过传入的task_id, request_id拼凑消息发送kafka,可供外部接口调用 :param request_id: :return: ''' _ins_info = ins_s.InstanceService().get_instance_info_by_requestid(request_id) if not _ins_info: logging.error('task %s : can not find instance info ' 'when retry create instance send kafka msg', task_id) return False, "can not find instance info", _ins_info['name'] if _ins_info['isdeleted'] == '1': logging.error('task %s : instance has been deleted ' 'when retry create instance send kafka msg', task_id) return False, "instance has been deleted", _ins_info['name'] _ins_host_ip = ins_s.get_hostip_of_instance(_ins_info['id']) _ins_hostpool_db_info = ins_s.get_hostpool_of_instance(_ins_info['id']) _ins_flavor_db_info = ins_s.get_flavor_of_instance(_ins_info['id']) if not _ins_host_ip or not _ins_hostpool_db_info or not _ins_flavor_db_info: logging.error('task %s : instance host, hostpool or flavor information' 'when retry create instance send kafka msg', task_id) return False, "instance host, hostpool or flavor information error", _ins_info['name'] # 获取虚拟机数据盘大小 src_instance_sys_disk_size = _ins_flavor_db_info['root_disk_gb'] data_disk_status, src_instance_data_disk_size = ins_s.get_data_disk_size_of_instance(_ins_info['id']) if not data_disk_status: logging.error('task %s : instance data disk size can not find' 'when retry create instance send kafka msg', task_id) return False, "instance data disk size can not find", _ins_info['name'] src_instance_disk_size = int(src_instance_data_disk_size) + int(src_instance_sys_disk_size) _ins_flavor_db_info['src_instance_disk_size'] = src_instance_disk_size vm_disk_gb = int(src_instance_disk_size) if int(src_instance_disk_size) > 50 else 50 # 获取虚拟机对应网段信息 segment_data = ins_s.get_net_segment_info_of_instance(_ins_info['id']) if not segment_data: logging.error('task %s : instance segment information can not find' 'when retry create instance send kafka msg', task_id) return False, "instance segment information can not find", _ins_info['name'] # 获取虚拟机所在机房类型 vm_env = hostpool_service.get_env_of_hostpool(_ins_hostpool_db_info['id']) if not vm_env: logging.error('task %s : instance env information can not find' 'when retry create instance send kafka msg', task_id) return False, "instance env information can not find", _ins_info['name'] ins_images = ins_s.get_images_of_instance(_ins_info['id']) if not ins_images: logging.error('task %s : instance image information can not find' 'when retry create instance send kafka msg', task_id) return False, "instance image information can not find", _ins_info['name'] else: instance_system = ins_images[0]['system'] image_name = ins_images[0]['name'] # 获取镜像信息,一个image_name可能对应多个id image_nums, image_data = image_service.ImageService().get_images_by_name(image_name) if image_nums <= 0: logging.error('task %s : instance image information can not find' 'when retry create instance send kafka msg', task_id) return False, "instance image information can not find", _ins_info['name'] #BT源信息获取 source_ip = _ins_info['clone_source_host'] source_vm = _ins_info['clone_source_vm'] #instance相关信息 instance_id = _ins_info['id'] uuid = _ins_info['uuid'] host_id = ins_h_s.get_ins_host_info_by_ins_id(instance_id)['host_id'] host_ip = ho_s.HostService().get_host_info(host_id)['ipaddress'] instance_name = _ins_info['name'] #获取source_disk_list source_instance_info = ins_s.InstanceService().get_instance_info_by_name(source_vm) if not source_instance_info: logging.info('克隆源vm %s 不存在' % source_vm) return False, "克隆源vm %s 不存在" % source_vm source_instance_id = source_instance_info['id'] instance_clone_create_data = ins_c_c.get_ins_clone_create_info_by_task_id(task_id) if not instance_clone_create_data: logging.info('获取克隆创建源vm信息失败') return False, "获取克隆创建源vm信息失败" clone_image_num = instance_clone_create_data['torrent_num'] source_disk_list = [] for i in range(int(clone_image_num)): clone_image_name = source_vm + '_' + task_id + '_' + str(i) source_disk_list.append(clone_image_name) # 获取源vm的镜像名称 sour_instance_image = ins_i_s.get_ins_image_info_by_ins_id(source_instance_id) total_size = instance_clone_create_data["total_size"] trans_type = instance_clone_create_data["trans_type"] http_port = instance_clone_create_data["http_port"] md5_check = instance_clone_create_data["md5_check"] sour_image_id = sour_instance_image['image_id'] sour_image_data = image_service.ImageService().get_image_info(sour_image_id) image_name = sour_image_data['name'] # 发送异步消息到队列 data = { "routing_key": "INSTANCE.CLONECREATE", "send_time": get_datetime_str(), "data": { "task_id": task_id, "source_ip":source_ip, "request_id": request_id, "instance_id":instance_id, "host_ip": host_ip, "uuid": uuid, "trans_type": trans_type, "http_port": http_port, "md5_check": md5_check, 'source_vm':source_vm, "hostname": instance_name, # 实例名 "memory_mb": _ins_flavor_db_info['memory_mb'], "vcpu": _ins_flavor_db_info['vcpu'], "ostype": instance_system, "user_id": _ins_info['owner'], "clone_image_num": clone_image_num, "disks":source_disk_list, "total_size": total_size, "image_name": image_name, "net_area_id": segment_data['net_area_id'], "networks": [ { "net_card_name": "br_bond0." + segment_data['vlan'], "ip": segment_data['ip_address'], "netmask": segment_data['netmask'], "dns1": segment_data['dns1'], "dns2": segment_data['dns2'], "mac": segment_data['mac'], "gateway": segment_data['gateway_ip'], "env": vm_env # SIT STG PRD DR } ] } } ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data) # 修改虚拟机状态为创建中 update_data = { 'status': VMStatus.CREATING, 'created_at': get_datetime_str(), 'updated_at': get_datetime_str() } where_data = { 'uuid': _ins_info['uuid'] } ins_s.InstanceService().update_instance_info(update_data, where_data) return 'done'
def extend_disk(instance_id): """ 扩展磁盘接口 :param instance_id: :return: """ c_system = '' c_version = None qemu_ga_update = False mount_point_list = [] if not instance_id: logging.info('no instance id when get configure info') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误") ins_data = ins_s.InstanceService().get_instance_info(instance_id) uuid = ins_data['uuid'] user_id = get_user()['user_id'] request_id = ins_s.generate_req_id() host_ip = ins_s.get_hostip_of_instance(instance_id) if not ins_data or not host_ip: data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} logging.info('instance %s data is no exist in db when get configure info', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, data=data_params, msg='数据库查询错误') if ins_data['create_source'] == '0': ins_images_data = ins_s.get_images_of_instance(instance_id) if ins_images_data: c_system = ins_images_data[0]['system'] c_version = ins_images_data[0]['version'] else: ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id) if ins_images_data: c_system = ins_images_data['os_type'] if ins_images_data['os_version'] and '6.6' in ins_images_data['os_version']: c_version = '6.6' elif ins_images_data['os_version'] and '7.2' in ins_images_data['os_version']: c_version = '7.2' # 更新qemu-guest-agent action到数据库,zitong wang 29th,9,2017 ins_a_s.add_disk_display_action_to_database(uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.START, 'start') # 更新qemu-guest-agent,获取所有挂载点的信息,add by zitongwang in 21th,9,2017 if c_system == "linux" and c_version: c_version = CentOS_Version.CentOS_7 if c_version >= '7.0' else CentOS_Version.CentOS_6 ins_a_s.add_disk_display_action_to_database(uuid, request_id, user_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT, ActionStatus.START, 'start') # 更新qemu-ga版本 vmManager.update_qemu_ga_instance(c_version,host_ip,ins_data['name']) connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name']) if not connect_instance: data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} msg = "libvirt连接建立失败,无法使用libvirt管理虚拟机" ins_a_s.add_disk_display_action_to_database(uuid, request_id, ActionStatus.FAILD, InstaceActions.INSTANCE_LIBVIRT_ERROR, msg) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, data=data_params, msg=msg) # 重新建立连接判断是否更新成功 flag, msg = connect_instance.test_update_command() qemu_ga_update = flag if flag: # 更新action数据库状态:更新成功 _message = "qemu_agent update successfully" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT, ActionStatus.SUCCSESS, _message) # 针对v2v机器,pvs显示的LV名称有问题 connect_instance.exec_qemu_command("pvscan") # 获得所有挂载点信息 command = "lsblk -r | awk '{print $7}' | awk NF | grep '^/' | grep -v '^/boot'" flag, msg = connect_instance.exec_qemu_command(command) mount_point = msg.splitlines() # 获取挂载点文件系统,大小,类型,挂载点信息 command = "lsblk -r | awk '{print $1" + "\\\" " + "\\\"" + "$4" + "\\\" " + "\\\"" + "$6" + "\\\" " + "\\\"" + "$7}'" flag, msg = connect_instance.exec_qemu_command(command) parts_info = msg.split('\n') parts_info.pop() mount_point_list = [] mount_list = [] for mount in mount_point: disk_info = {} mount_data = filter(lambda x: x.split(' ')[-1] == mount, parts_info) data = mount_data[0].split(' ') disk_info['mount_point'] = data[-1] # 存在数据就返回 if disk_info['mount_point'] in mount_list: continue else: mount_list.append(disk_info['mount_point']) disk_info['mount_partition_name'] = data[0] disk_info['mount_point_size'] = float(data[1][0:-1]) if data[1][-1].endswith('G') else float( data[1][0:-1]) / 1024 disk_info['mount_partition_type'] = data[2] command = "df -P '%s'| awk 'NR==2 {print $5}'" % mount flag, msg = connect_instance.exec_qemu_command(command) disk_info['mount_point_use'] = msg.strip() mount_point_list.append(disk_info) data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} _message = "linux os disk information display successfully" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.SUCCSESS, _message) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=data_params) else: # 更新qmeu-ga失败 _message = "qemu_agent update failed" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT, ActionStatus.FAILD, _message) data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, data=data_params, msg='qemu update fail') elif c_system == "windows": connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name']) disk_info = connect_instance.get_configure_disk_device(uuid) storage_instance = vmManager.libvirt_get_connect(host_ip, conn_type='storage', vmname=ins_data['name'], poolname=uuid) mount_point_list = [] for x in disk_info: d = {} block_info = storage_instance.get_disk_size(x['image']) d.setdefault('mount_point', x['dev']) d.setdefault('mount_point_size', '%.1f' % (float(block_info[0]) / 1073741824)) d.setdefault('mount_point_use', '%.2f' % (float(block_info[1]) / block_info[0] * 100)) d.setdefault('mount_partition_name', "") d.setdefault('mount_partition_type', "") mount_point_list.append(d) qemu_ga_update = True data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} _message = "disk information display successfully" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.SUCCSESS, _message) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=data_params, msg=_message) else: data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} _message = "os type unknown, please call kvm administrators" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.FAILD, _message) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, data=data_params, msg=_message)
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='修改配置成功')