def disconnect_session(self, session): Logger.info("SessionManagement::disconnect %s"%(session.id)) if session.user.created or not session.domain.manage_user(): # Doesn't have to disconnect the session if the user was never created try: sessid = TS.getSessionID(session.user.name) except Exception: Logger.exception("RDP server dialog failed ... ") return False try: status = TS.getState(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return if status in [TS.STATUS_LOGGED]: Logger.info("must disconnect ts session %s user %s"%(sessid, session.user.name)) try: TS.disconnect(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return session.switch_status(Session.SESSION_STATUS_INACTIVE)
def disconnect_session(self, session): Logger.info("SessionManagement::disconnect %s" % (session.id)) if session.user.created or not session.domain.manage_user(): # Doesn't have to disconnect the session if the user was never created try: sessid = TS.getSessionID(session.user.name) except Exception: Logger.exception("RDP server dialog failed ... ") return False try: status = TS.getState(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return if status in [TS.STATUS_LOGGED]: Logger.info("must disconnect ts session %s user %s" % (sessid, session.user.name)) try: TS.disconnect(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return session.switch_status(Session.SESSION_STATUS_INACTIVE)
def init(self): Logger.debug("ApplicationServer init") try: TS.getList() except Exception: Logger.exception("RDP server dialog failed ... exiting") return if not System.groupExist(self.manager.ts_group_name): Logger.error("The group '%s' doesn't exist" % (self.manager.ts_group_name)) return False if not System.groupExist(self.manager.ovd_group_name): if not System.groupCreate(self.manager.ovd_group_name): return False if not self.manager.purgeGroup(): Logger.error("Unable to purge group") return False if Config.clean_dump_archive: self.purgeArchives() if Config.thread_count is None: cpuInfos = System.getCPUInfos() vcpu = cpuInfos[0] ram_total = System.getRAMTotal() ram = int(round(ram_total / 1024.0 / 1024.0)) nb_thread = int(round(1 + (ram + vcpu * 2) / 3)) else: nb_thread = Config.thread_count Logger._instance.setQueue(self.logging_queue, True) for _ in xrange(nb_thread): self.threads.append( SessionManagement(self.manager, self.sessions_spooler, self.sessions_spooler2, self.sessions_sync, self.logging_queue)) if self.canManageApplications(): self.apt = Apt() self.apt.init() self.threads.append(self.apt) Logger.info( "ApplicationServer:: retrieve all applications installed (can take some time)" ) self.updateApplications() return True
def req_user_loggedin(self, request): try: document = minidom.parseString(request["data"]) rootNode = document.documentElement if rootNode.nodeName != "user": raise Exception("invalid root node") if not rootNode.hasAttribute("login"): raise Exception("invalid root node") login = rootNode.getAttribute("login") except: Logger.warn("Invalid xml input !!") doc = Document() rootNode = doc.createElement('error') rootNode.setAttribute("id", "usage") doc.appendChild(rootNode) return self.req_answer(doc) try: ret = TS.getSessionID(login) except Exception: Logger.exception("RDP server dialog failed ... ") doc = Document() rootNode = doc.createElement('error') rootNode.setAttribute("id", "internalerror") doc.appendChild(rootNode) return self.req_answer(doc) rootNode.setAttribute("loggedin", str((ret is not None)).lower()) return self.req_answer(document)
def init(self): Logger.debug("ApplicationServer init") try: TS.getList() except Exception: Logger.exception("RDP server dialog failed ... exiting") return if not System.groupExist(self.manager.ts_group_name): Logger.error("The group '%s' doesn't exist"%(self.manager.ts_group_name)) return False if not System.groupExist(self.manager.ovd_group_name): if not System.groupCreate(self.manager.ovd_group_name): return False if not self.manager.purgeGroup(): Logger.error("Unable to purge group") return False if Config.clean_dump_archive: self.purgeArchives() if Config.thread_count is None: cpuInfos = System.getCPUInfos() vcpu = cpuInfos[0] ram_total = System.getRAMTotal() ram = int(round(ram_total / 1024.0 / 1024.0)) nb_thread = int(round(1 + (ram + vcpu * 2)/3)) else: nb_thread = Config.thread_count Logger._instance.setQueue(self.logging_queue, True) for _ in xrange(nb_thread): self.threads.append(SessionManagement(self.manager, self.sessions_spooler, self.sessions_spooler2, self.sessions_sync, self.logging_queue)) if self.canManageApplications(): self.apt = Apt() self.apt.init() self.threads.append(self.apt) Logger.info("ApplicationServer:: retrieve all applications installed (can take some time)") self.updateApplications() return True
def logoff_user(self, user): Logger.info("SessionManagement::logoff_user %s"%(user.name)) if user.infos.has_key("tsid"): sessid = user.infos["tsid"] try: status = TS.getState(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return if status in [TS.STATUS_LOGGED, TS.STATUS_DISCONNECTED]: Logger.info("must log off ts session %s user %s"%(sessid, user.name)) try: TS.logoff(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return del(user.infos["tsid"])
def logoff_user(self, user): Logger.info("SessionManagement::logoff_user %s" % (user.name)) if user.infos.has_key("tsid"): sessid = user.infos["tsid"] try: status = TS.getState(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return if status in [TS.STATUS_LOGGED, TS.STATUS_DISCONNECTED]: Logger.info("must log off ts session %s user %s" % (sessid, user.name)) try: TS.logoff(sessid) except Exception: Logger.exception("RDP server dialog failed ... ") return del (user.infos["tsid"])
def destroy_session(self, session): Logger.info("SessionManagement::destroy %s" % (session.id)) if session.user.created or not session.domain.manage_user(): # Doesn't have to destroy the session if the user was never created try: sessid = TS.getSessionID(session.user.name) except Exception: Logger.exception("RDP server dialog failed ... ") return if sessid is not None: session.user.infos["tsid"] = sessid self.logoff_user(session.user) session.uninstall_client() if session.domain.manage_user(): self.destroy_user(session.user) session.domain.onSessionEnd() session.switch_status(Session.SESSION_STATUS_DESTROYED)
def destroy_session(self, session): Logger.info("SessionManagement::destroy %s"%(session.id)) if session.user.created or not session.domain.manage_user(): # Doesn't have to destroy the session if the user was never created try: sessid = TS.getSessionID(session.user.name) except Exception: Logger.exception("RDP server dialog failed ... ") return if sessid is not None: session.user.infos["tsid"] = sessid self.logoff_user(session.user) session.uninstall_client() if session.domain.manage_user(): self.destroy_user(session.user) session.domain.onSessionEnd() session.switch_status(Session.SESSION_STATUS_DESTROYED)
class Manager: ts_group_name = TS.getUsersGroup() ovd_group_name = "OVDUsers" def __init__(self, smManager): self.smManager = smManager def send_session_status(self, session): try: doc = Document() rootNode = doc.createElement('session') rootNode.setAttribute("id", session.id) rootNode.setAttribute("status", session.status) if session.status == Session.SESSION_STATUS_DESTROYED and session.end_status is not None: rootNode.setAttribute("reason", session.end_status) doc.appendChild(rootNode) except Exception: Logger.exception("ApplicationServer: send_session_status") response = self.smManager.send_packet("/session/status", doc) Logger.debug2("ApplicationServer: send_session_status: %s" % (response)) if response is False: Logger.warn("ApplicationServer: unable to send session status") else: response.close() response = None def send_session_dump(self, session): dumps = {} for path in glob.glob( os.path.join(Config.spool_dir, "sessions dump archive", "%s %s-*" % (session.id, session.user.name))): try: f = file(path, "r") except IOError, err: continue data = f.read() f.close() name = os.path.basename(path) name = name[len("%s %s-" % (session.id, session.user.name)):] dumps[name] = data data = session.log.get_full_log() if len(data) > 0: dumps["server.log"] = data try: doc = Document() rootNode = doc.createElement('session') rootNode.setAttribute("id", session.id) for (name, data) in dumps.items(): textNode = doc.createTextNode(base64.encodestring(data)) node = doc.createElement('dump') node.setAttribute("name", name) node.appendChild(textNode) rootNode.appendChild(node) doc.appendChild(rootNode) except Exception: Logger.exception("ApplicationServer: send_session_dump") response = self.smManager.send_packet("/session/dump", doc) Logger.debug2("ApplicationServer: send_session_dump: %s" % (response)) if response is False: Logger.warn("ApplicationServer: unable to send session dump") else: response.close() response = None
class Role(AbstractRole): sessions = {} sessions_spooler = None def __init__(self, main_instance): AbstractRole.__init__(self, main_instance) self.sessions = {} self.locked_sessions = [] self.sessions_spooler = MPQueue.Queue() self.sessions_spooler2 = MPQueue.Queue() self.sessions_sync = MPQueue.Queue() self.logging_queue = MPQueue.Queue() self.manager = Manager(self.main_instance.smRequestManager) self.threads = [] self.applications = {} self.applications_id_SM = {} self.applications_mutex = threading.Lock() self.static_apps = ApplicationsStatic( self.main_instance.smRequestManager) self.static_apps_must_synced = False self.static_apps_lock = threading.Lock() self.scripts = Scripts(self.main_instance.smRequestManager) self.scripts_lock = threading.Lock() self.scripts_must_synced = False def init(self): Logger.debug("ApplicationServer init") try: TS.getList() except Exception: Logger.exception("RDP server dialog failed ... exiting") return if not System.groupExist(self.manager.ts_group_name): Logger.error("The group '%s' doesn't exist" % (self.manager.ts_group_name)) return False if not System.groupExist(self.manager.ovd_group_name): if not System.groupCreate(self.manager.ovd_group_name): return False if not self.manager.purgeGroup(): Logger.error("Unable to purge group") return False if Config.clean_dump_archive: self.purgeArchives() if Config.thread_count is None: cpuInfos = System.getCPUInfos() vcpu = cpuInfos[0] ram_total = System.getRAMTotal() ram = int(round(ram_total / 1024.0 / 1024.0)) nb_thread = int(round(1 + (ram + vcpu * 2) / 3)) else: nb_thread = Config.thread_count Logger._instance.setQueue(self.logging_queue, True) for _ in xrange(nb_thread): self.threads.append( SessionManagement(self.manager, self.sessions_spooler, self.sessions_spooler2, self.sessions_sync, self.logging_queue)) if self.canManageApplications(): self.apt = Apt() self.apt.init() self.threads.append(self.apt) Logger.info( "ApplicationServer:: retrieve all applications installed (can take some time)" ) self.updateApplications() return True @staticmethod def getName(): return "ApplicationServer" def switch_to_production(self): self.setStaticAppsMustBeSync(True) self.setScriptsMustBeSync(True) def order_stop(self): AbstractRole.order_stop(self) for session in self.sessions.values(): self.manager.session_switch_status( session, Session.SESSION_STATUS_WAIT_DESTROY) self.spool_action("destroy", session.id) def force_stop(self): AbstractRole.force_stop(self) for thread in self.threads: thread.terminate() for thread in self.threads: thread.join() def finalize(self): Logger._instance.setThreadedMode(False) self.update_locked_sessions() for session in self.sessions.values(): self.manager.session_switch_status( session, Session.SESSION_STATUS_WAIT_DESTROY) System.prepareForSessionActions() cleaner = SessionManagement(self.manager, None, None, None, None) for session in self.sessions.values(): session.end_status = Session.SESSION_END_STATUS_SHUTDOWN cleaner.destroy_session(session) self.manager.purgeGroup() Profile.cleanup() def get_session_from_login(self, login_): for session in self.sessions.values(): if session["login"] == login_: return session return None def run(self): Logger._instance.lock.acquire() Logger._instance.close() for thread in self.threads: thread.start() thread.known_death = False Logger._instance.lock.release() t0_update_app = time.time() self.status = Role.STATUS_RUNNING while self.loop: if self.status == Role.STATUS_ERROR: break if self.status == Role.STATUS_STOPPING and len(self.sessions) == 0: break while True: try: session = self.sessions_sync.get_nowait() except Queue.Empty, e: break except (EOFError, socket.error): Logger.debug("APS:: Role stopping") self.status = Role.STATUS_ERROR break if not self.sessions.has_key(session.id): Logger.warn( "Session %s do not exist, session information are ignored" % (session.id)) continue if session.status != self.sessions[session.id].status: self.manager.session_switch_status(session, session.status) if session.status == Session.SESSION_STATUS_DESTROYED: del (self.sessions[session.id]) else: self.sessions[session.id] = session if self.status == Role.STATUS_ERROR: break self.update_locked_sessions() for session in self.sessions.values(): try: ts_id = TS.getSessionID(session.user.name) except Exception: Logger.exception("RDP server dialog failed ... exiting") self.status = Role.STATUS_ERROR break if ts_id is None: if session.status in [ Session.SESSION_STATUS_ACTIVE, Session.SESSION_STATUS_INACTIVE ]: Logger.error( "Weird, running session %s no longer exist" % (session.id)) if session.status == Session.SESSION_STATUS_ACTIVE: # User has logged off session.end_status = Session.SESSION_END_STATUS_NORMAL if session.status not in [ Session.SESSION_STATUS_WAIT_DESTROY, Session.SESSION_STATUS_DESTROYED, Session.SESSION_STATUS_ERROR ]: self.manager.session_switch_status( session, Session.SESSION_STATUS_WAIT_DESTROY) self.spool_action("destroy", session.id) continue try: ts_status = TS.getState(ts_id) except Exception: Logger.exception("RDP server dialog failed ... exiting") self.status = Role.STATUS_ERROR break if session.status == Session.SESSION_STATUS_INITED: if ts_status is TS.STATUS_LOGGED: self.manager.session_switch_status( session, Session.SESSION_STATUS_ACTIVE) if not session.domain.manage_user(): self.spool_action("manage_new", session.id) continue if ts_status is TS.STATUS_DISCONNECTED: self.manager.session_switch_status( session, Session.SESSION_STATUS_INACTIVE) continue if session.status == Session.SESSION_STATUS_ACTIVE and ts_status is TS.STATUS_DISCONNECTED: self.manager.session_switch_status( session, Session.SESSION_STATUS_INACTIVE) continue if session.status == Session.SESSION_STATUS_INACTIVE and ts_status is TS.STATUS_LOGGED: self.manager.session_switch_status( session, Session.SESSION_STATUS_ACTIVE) if not session.domain.manage_user(): self.spool_action("manage_new", session.id) continue if self.isStaticAppsMustBeSync(): self.static_apps.synchronize() self.setStaticAppsMustBeSync(False) if self.isScriptsMustBeSync(): self.scripts.synchronize() self.setScriptsMustBeSync(False) for thread in self.threads: if not thread.known_death and not thread.is_alive(): Logger.error( "SessionManagement process (pid: %d, name: %s) is dead (return code: %d) while managed session '%s'" % (thread.pid, repr(thread.name), thread.exitcode, repr(thread.current_session_id.value))) thread.known_death = True t1 = time.time() if t1 - t0_update_app > 30: self.updateApplications() t0_update_app = time.time() else: time.sleep(1)