def client_except_exit(self, client, message=None): terminal_mac = client.mac terminal_ip = client.client_ip terminal_port = client.client_port logger.info("client_except_exit: %s" % terminal_mac) if terminal_mac in self.clients.keys(): self.clients[terminal_mac] = client self.clients[terminal_mac].heartbeat = False # self.clients[terminal_mac].alive_timestamp = dt.datetime.now() ip_port = self.ip_port_str(terminal_ip, terminal_port) self.ip_port_mac[ip_port] = terminal_mac thread_id = ctypes.CDLL('libc.so.6').syscall(186) logger.info( "terminal clients: %s pid: %s, ppid: %s, tid: %s, t_ident: %s" % (self.clients, os.getpid(), os.getppid(), thread_id, threading.currentThread().ident)) # 通知服务端 _data = { "cmd": "terminal_except_exit", "data": { "mac": terminal_mac, "ip": client.client_ip, } } ret = voi_terminal_post("/api/v1/voi/terminal/task/", _data) logger.info("voi terminal server return: %s" % ret) if ret.get("code") != 0: logger.error("voi terminal client_except_exit error: %s" % ret) return ret else: logger.debug("voi terminal client_except_exit: %s is not exist" % terminal_mac) logger.info("client %s, end......" % client) return get_error_result("Success", "en")
def client_torrent_upload(self, client, message=None): """ 客户端上传种子 """ logger.info("client upload template torrent file: %s, message: %s" % (client, message.keys())) message.pop('supplementary') message.pop('token') # message["service_name"] = # payload = message["payload"] # message["payload"] = base64.b64encode(payload).decode("utf-8") # message["payload"] = payload message["mac"] = client.mac message["ip"] = client.client_ip # message["data"] = base64.b64encode(message["data"].encode("utf-8")).decode("utf-8") message["is_json"] = True # terminal_mac = client.mac # terminal_ip = client.client_ip _data = {"cmd": "torrent_upload", "data": message} ret = voi_terminal_post("/api/v1/voi/terminal/task/", _data) logger.info("voi terminal server return: %s" % ret) if ret.get("code") != 0: logger.error("voi terminal client_except_exit error: %s" % ret) return ret logger.info("client upload template torrent file success!!!!") return ret
def delete_group(self, group_uuid): group = voi_api.get_item_with_first(models.YzyVoiGroup, {"uuid": group_uuid}) if not group: logger.error("group: %s not exist", group_uuid) return get_error_result("GroupNotExists", name='') if constants.EDUCATION_DESKTOP == group.group_type: desktop = voi_api.get_item_with_first(models.YzyVoiDesktop, {"group_uuid": group_uuid}) if desktop: logger.error("group already in use", group_uuid) return get_error_result("GroupInUse", name=group.name) binds = voi_api.get_item_with_all(models.YzyVoiTemplateGroups, {"group_uuid": group_uuid}) for bind in binds: bind.soft_delete() group.soft_delete() logger.info("delete voi group %s success", group_uuid) ret = voi_terminal_post( "/api/v1/voi/terminal/command", { "handler": "WebTerminalHandler", "command": "delete_group", "data": { "group_uuid": group_uuid } }) return ret
def client_terminal_logout(self, client, message=None): logger.info("client_logout: %s" % client) terminal_mac = client.mac if terminal_mac in self.clients.keys(): self.clients.pop(terminal_mac) thread_id = ctypes.CDLL('libc.so.6').syscall(186) logger.info( "terminal clients: %s pid: %s, ppid: %s, tid: %s, t_ident: %s" % (self.clients, os.getpid(), os.getppid(), thread_id, threading.currentThread().ident)) # 通知服务端 _data = { "cmd": "terminal_logout", "data": { "mac": terminal_mac, "ip": client.client_ip, "port": client.client_port } } ret = voi_terminal_post("/api/v1/voi/terminal/task/", _data) logger.info("voi terminal server return: %s" % ret) if ret.get("code") != 0: logger.error("voi terminal client_logout error: %s" % ret) logger.info("client %s, end......" % client) return ret else: logger.error("voi terminal logout error: %s is not exist" % terminal_mac) logger.info("client %s, end......" % client) return get_error_result("Success", "en")
def notify_terminal(self, desktop_group_uuid=None, group_uuid=None): # get group_uuid logger.info("desktop_group_uuid={}, group_uuid={}".format( desktop_group_uuid, group_uuid)) if not group_uuid and desktop_group_uuid: qry = db_api.get_item_with_first(models.YzyVoiDesktop, {'uuid': desktop_group_uuid}) group_uuid = qry.group_uuid if not group_uuid: logger.error('group_uuid is null, do not notify terminals') return requst_data = { "handler": "WebTerminalHandler", "command": "update_desktop_group_notify", "data": { "group_uuid": group_uuid } } ret = voi_terminal_post("/api/v1/voi/terminal/command/", requst_data) if ret.get("code", -1) != 0: logger.error("voi_terminal_post request: {}, ret: {}".format( requst_data, ret)) return ret logger.info("voi_terminal_post request: {}, ret: {}".format( requst_data, ret))
def client_biz_processor(self, client, is_req, seq_id, handler_name, message): logger.debug( "client: {}, is_req: {}, seq_id: {}, handler_name: {} message: {}". format(client, is_req, seq_id, handler_name, message)[:1000]) # client, is_req, seq_id, handler_name, message)) if message.get("mac", None): message["mac"] = message["mac"].upper() terminal_mac = client.mac method_name = "client_%s" % handler_name if (not message.get('token', None) and method_name != "client_terminal_login") or \ (message.get('token', None) and self.clients.get(terminal_mac, None) and (message['token'].decode('utf-8') != self.clients[terminal_mac].token)): ret = get_error_result("TerminalTokenError", msg="en") logger.error("voi terminal token error: %s" % client) return ret if hasattr(self, method_name): func = getattr(self, method_name) ret = func(client, message) logger.debug( "Client request method_name(no flask request): {}, ret: {}". format(method_name, ret)) return ret logger.info("terminal_mac: {}, client: {}, method_name: {}".format( terminal_mac, client, method_name)) if terminal_mac in self.clients.keys(): thread_id = ctypes.CDLL('libc.so.6').syscall(186) thread_ident = threading.currentThread().ident logger.info( "terminal clients: %s pid: %s, ppid: %s, tid: %s, t_ident: %s" % (self.clients, os.getpid(), os.getppid(), thread_id, thread_ident)) message.pop('supplementary') message.pop('token') message["service_name"] = handler_name message["terminal_mac"] = terminal_mac message["terminal_ip"] = client.client_ip # 通知服务端 _data = { # "cmd": handler_name if is_req else (handler_name + "_response"), "cmd": handler_name if is_req else "command_response", "data": message } logger.info("voi terminal request server : %s" % _data) ret = voi_terminal_post("/api/v1/voi/terminal/task/", _data) logger.info("voi terminal server return: %s" % ret) else: ret = get_error_result("TerminalNotLogin", msg="en") logger.error("voi terminal not login: %s" % client) client.socket_client.socket.close() return ret
def client_terminal_login(self, client, message=None): logger.info("client %s login, start......" % client) terminal_mac = client.mac terminal_ip = client.client_ip terminal_port = client.client_port client.heartbeat = client.status self.clients[terminal_mac] = client ip_port = self.ip_port_str(terminal_ip, terminal_port) self.ip_port_mac[ip_port] = terminal_mac thread_id = ctypes.CDLL('libc.so.6').syscall(186) logger.info( "terminal clients: %s pid: %s, ppid: %s, tid: %s, t_ident: %s" % (self.clients, os.getpid(), os.getppid(), thread_id, threading.currentThread().ident)) # 通知服务端 _data = { "cmd": "terminal_login", "data": { "mac": terminal_mac, "ip": client.client_ip, "status": client.status, "port": client.client_port, "desktop_uuid": message.get("desktop_uuid", "") } } ret = voi_terminal_post("/api/v1/voi/terminal/task/", _data) logger.info("voi terminal server return: %s" % ret) if ret.get("code") != 0: logger.error("voi terminal login error: %s" % ret) else: token = ret.get("data").get("token", "") # self.clients[terminal_mac].token = token client.token = token client.alive_timestamp = dt.datetime.now() self.token_clients[token] = client logger.info("client %s, end......" % client) return ret
def create_share_disk_torrent(self, disk_info, version): disks = list() disk_uuid = disk_info["uuid"] base_path = disk_info["base_path"] backing_dir = os.path.join(base_path, constants.IMAGE_CACHE_DIRECTORY_NAME) for i in range(version + 1): file_path = os.path.join( backing_dir, constants.VOI_SHARE_BASE_PREFIX % str(i) + disk_uuid) if os.path.exists(file_path): torrent_path = file_path + ".torrent" disks.append({ "file_path": file_path, "torrent_path": torrent_path }) data = {"command": "create_torrent", "data": {"torrents": disks}} ret = voi_terminal_post("/api/v1/voi/terminal/command/", data) if ret.get("code", -1) != 0: logger.error( "threading voi share disk create disk fail torrent :%s", ret) return ret logger.info("threading voi share disk create disk torrent success!!!") return ret
def check_client_heartbeat(self): try: self.reset_all_terminals() # set loop_seconds must > 10 # exit_count = 6 # cal_count = 0 loop_seconds = 10 off_line = 2 * loop_seconds max_off_line = 2 * 60 # update_loop_seconds = 10 while True: # is_exit_flag = False # if cal_count >= exit_count: # is_exit_flag = True # cal_count = 0 tmp_timestamp = dt.datetime.now() logger.debug("check clients heartbeat {}".format(self.clients)) online_macs = list() for mac in list(self.clients.keys()): try: client = self.clients[mac] online_macs.append({ "mac": mac, "status": int(client.heartbeat) }) alive_timestamp = client.alive_timestamp time_seconds = (tmp_timestamp - alive_timestamp).seconds if off_line < time_seconds < max_off_line: client.heartbeat = False elif time_seconds >= max_off_line: client.status = TerminalStatus.OFF if client.socket_client.socket: client.socket_client.socket.close() logger.warning( 'client: {} no heartbeat, close socket'. format(client)) self.clients.pop(mac) logger.info("clear client: {}".format(client)) # self.del_client_by_ip(client.client_ip, client.client_port) # update database status offline # 通知服务端500 _data = { "cmd": "terminal_except_exit", "data": { "mac": client.mac, "ip": client.client_ip } } ret = voi_terminal_post( "/api/v1/voi/terminal/task/", _data) logger.info( "voi terminal except exit: {}, server return: {}" .format(client, ret)) if ret.get("code") != 0: logger.error( "voi terminal except exit: {}, server return: {}" .format(_data, ret)) except Exception as e: logger.error("voi terminal check heartbeat error", exc_info=True) continue if online_macs: # macs_str = ",".join(online_macs) logger.debug("check clients heartbeat online macs: %s" % online_macs) # 通知终端在线 req_data = { "cmd": "terminal_online_update", "data": { "terminals": online_macs, } } ret = voi_terminal_post("/api/v1/voi/terminal/task/", req_data) logger.debug( "check clients heartbeat update terminals online macs: %s, ret: %s" % (online_macs, ret)) time.sleep(loop_seconds) # cal_count += 1 except Exception as err: logger.error(err) logger.error(''.join(traceback.format_exc()))
def reset_all_terminals(self): _data = { "cmd": "restart_reset_terminals", } ret = voi_terminal_post("/api/v1/voi/terminal/task/", _data)
def order_terminal_desktop_ip(self, data): """ "terminal_id_list": terminal_id_list, "group_uuid": group_uuid, "terminal_mac_list": terminal_mac_list """ logger.info("order terminal desktop ip data: {}".format(data)) try: group_uuid = data.get("group_uuid", "") terminal_mac_list = data.get("terminal_mac_list", "") terminal_id_list = data.get("terminal_id_list", "") if terminal_mac_list: terminals_list = list(zip(terminal_id_list, terminal_mac_list)) terminals_list = sorted(terminals_list, key=lambda x: x[0]) else: logger.warning( 'request terminal_mac_list is null, please check!!1') return build_result("Success") # group_uuid get all desktop groups qry_desktop_groups = db_api.get_item_with_all( models.YzyVoiDesktop, {'group_uuid': group_uuid}) for desktop_group in qry_desktop_groups: if not desktop_group.use_bottom_ip and desktop_group.ip_detail: ip_detail = json.loads(desktop_group.ip_detail) desktop_is_dhcp = ip_detail.get("auto", True) if not desktop_is_dhcp: desktop_start_ip = ip_detail.get("start_ip", "") desktop_mask = ip_detail.get("netmask", "") desktop_gateway = ip_detail.get("gateway", "") desktop_dns1 = ip_detail.get("dns_master", "") desktop_dns2 = ip_detail.get("dns_slave", "") netmask_bits = netaddr.IPAddress( desktop_mask).netmask_bits() network = ipaddress.ip_interface( desktop_start_ip + '/' + str(netmask_bits)).network desktop_ip_pool = [ x for x in network.hosts() if x >= ipaddress.IPv4Address(desktop_start_ip) ] if desktop_ip_pool: for terminal_id, terminal_mac in terminals_list: set_ip_detail = {} if desktop_ip_pool: desktop_ip = min(desktop_ip_pool) set_ip_detail = { "desktop_is_dhcp": 0, "desktop_ip": desktop_ip.compressed, "desktop_mask": desktop_mask, "desktop_gateway": desktop_gateway, "desktop_dns1": desktop_dns1, "desktop_dns2": desktop_dns2, } desktop_ip_pool.remove(desktop_ip) logger.debug( 'terminal_id: {}, terminal_mac: {}, ip: {}' .format(terminal_id, terminal_mac, desktop_ip)) else: # no more available ip, set desktop ip use bottom ip requst_data = { "handler": "WebTerminalHandler", "command": "get_terminal_ip", "data": { 'mac': terminal_mac } } ret = voi_terminal_post( "/api/v1/voi/terminal/command/", requst_data) if ret.get("code", -1) != 0: logger.error( "voi_terminal_post request: {}, ret: {}" .format(requst_data, ret)) return ret bottom_ip = ret.get("data", None) set_ip_detail = { "desktop_is_dhcp": 0, "desktop_ip": bottom_ip['ip'], "desktop_mask": bottom_ip['mask'], "desktop_gateway": bottom_ip['gateway'], "desktop_dns1": bottom_ip['dns1'], "desktop_dns2": bottom_ip['dns2'], } # update database table set_ip_detail db_api.update_voi_terminal_desktop_bind( desktop_group.uuid, terminal_mac, set_ip_detail) else: logger.warning( 'desktop group ip setup error, no available ip' ) return build_result("Success") except Exception as e: logger.error("", exc_info=True) return build_result("OtherError")