[X2Go-Commits] python-x2go.git - brokerclient (branch) updated: efa3c772705eb18d76de85a1da2441d916e9aec3

X2Go dev team git-admin at x2go.org
Tue Jan 7 16:19:31 CET 2014


The branch, brokerclient has been updated
       via  efa3c772705eb18d76de85a1da2441d916e9aec3 (commit)
      from  1e9e565968956a3974eefa21765b7710db207b0d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 x2go/backends/control/stdout.py         |   72 +++++++++++++++++++------------
 x2go/backends/profiles/https_broker.py  |    3 +-
 x2go/backends/profiles/sessions_file.py |    3 +-
 x2go/backends/profiles/win_registry.py  |    3 +-
 x2go/backends/terminal/stdout.py        |   23 ++++------
 x2go/cache.py                           |   11 +++--
 x2go/client.py                          |   14 +++---
 x2go/guardian.py                        |    2 +
 x2go/session.py                         |   33 +++++++++++---
 x2go/x2go_exceptions.py                 |   10 ++---
 10 files changed, 106 insertions(+), 68 deletions(-)

The diff of changes is:
diff --git a/x2go/backends/control/stdout.py b/x2go/backends/control/stdout.py
index 722eb61..42ae7c9 100644
--- a/x2go/backends/control/stdout.py
+++ b/x2go/backends/control/stdout.py
@@ -56,21 +56,13 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
     @type loglevel: int
 
     """
-    associated_terminals = {}
-    terminated_terminals = []
-
-    _session_auth_rsakey = None
-    _remote_home = None
-    _remote_group = {}
-
-    x2go_listsessions_cache = None
-
     def __init__(self,
                  terminal_backend=_X2goTerminalSession,
                  info_backend=_X2goServerSessionInfo,
                  list_backend=_X2goServerSessionList,
                  proxy_backend=_X2goProxy,
                  use_listsessions_cache=True,
+                 controlled_session=None,
                  logger=None, loglevel=log.loglevel_DEFAULT,
                  *args, **kwargs):
         """\
@@ -79,12 +71,25 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         currently running sessions on a connected X2go server.
 
         """
+        self.associated_terminals = {}
+        self.terminated_terminals = []
+        self.controlled_sessions = {}
+
+        self._session_auth_rsakey = None
+        self._remote_home = None
+        self._remote_group = {}
+
+        self.x2go_listsessions_cache = None
+
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
             self.logger = copy.deepcopy(logger)
         self.logger.tag = __NAME__
 
+        if controlled_session is not None:
+            self.controlled_sessions[controlled_session._X2goSession__get_uuid()] = controlled_session
+
         self._terminal_backend = terminal_backend
         self._info_backend = info_backend
         self._list_backend = list_backend
@@ -233,17 +238,17 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
             key_filename = None
             pkey = None
 
-        self.logger('connecting to %s' % hostname, log.loglevel_NOTICE)
+        self.logger('connecting to %s' % hostname, loglevel=log.loglevel_NOTICE)
 
         if (key_filename or pkey):
             try:
-                self.logger('trying SSH pub/priv key authentication with server', log.loglevel_DEBUG)
+                self.logger('trying SSH pub/priv key authentication with server', loglevel=log.loglevel_DEBUG)
                 paramiko.SSHClient.connect(self, hostname, port=port, username=username, pkey=pkey,
                                            key_filename=key_filename, timeout=timeout, allow_agent=allow_agent, 
                                            look_for_keys=look_for_keys)
             except paramiko.AuthenticationException, e:
                 if password:
-                    self.logger('next auth mechanism we\'ll try is keyboard-interactive authentication', log.loglevel_DEBUG)
+                    self.logger('next auth mechanism we\'ll try is keyboard-interactive authentication', loglevel=log.loglevel_DEBUG)
                     paramiko.SSHClient.connect(self, hostname, port=port, username=username, password=password,
                                                timeout=timeout, allow_agent=allow_agent, 
                                                look_for_keys=look_for_keys)
@@ -252,7 +257,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
 
         # if there is not private key, we will use the given password
         elif password:
-            self.logger('performing SSH keyboard-interactive authentication with server', log.loglevel_DEBUG)
+            self.logger('performing SSH keyboard-interactive authentication with server', loglevel=log.loglevel_DEBUG)
             paramiko.SSHClient.connect(self, hostname, port=port, username=username, password=password, 
                                        timeout=timeout, allow_agent=allow_agent, look_for_keys=look_for_keys)
 
@@ -282,8 +287,11 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         STILL UNDOCUMENTED
 
         """
-        self.x2go_listsessions_cache.stop_thread()
-        del self.x2go_listsessions_cache
+        if self.x2go_listsessions_cache is not None:
+            self.x2go_listsessions_cache.stop_thread()
+            del self.x2go_listsessions_cache
+            self.x2go_listsessions_cache = None
+
         t_names = self.associated_terminals.keys()
         for  t_obj in self.associated_terminals.values():
             try:
@@ -293,6 +301,11 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
             del t_obj
         for t_name in t_names:
             del self.associated_terminals[t_name]
+
+        self._remote_home = None
+        self._remote_group = {}
+
+        self._session_auth_rsakey = None
         if self.get_transport() is not None:
             self.get_transport().close()
 
@@ -325,8 +338,8 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         @rtype: C{bool}
 
         """
-        if self.get_transport().get_username() not in self._x2go_remote_group('x2gousers'):
-            raise x2go_exceptions.X2goSessionException('remote user %s is not member of X2go server group x2gousers' % self.get_transport().get_username())
+        if not self.is_x2gouser(self.get_transport().get_username()):
+            raise x2go_exceptions.X2goUserException('remote user %s is not member of X2go server group x2gousers' % self.get_transport().get_username())
 
         if session_name is not None:
             session_info = self.list_sessions(refresh_cache=True)[session_name]
@@ -385,14 +398,19 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
 
         elif no_cache or refresh_cache or (self.use_listsessions_cache is False) or (self.x2go_listsessions_cache is None):
 
-            (stdin, stdout, stderr) = self._x2go_exec_command("x2golistsessions")
+            try:
+                (stdin, stdout, stderr) = self._x2go_exec_command("x2golistsessions")
+
+                _stdout_read = stdout.read()
+                _listsessions = self._list_backend(_stdout_read, info_backend=self._info_backend).sessions
+                if refresh_cache and self.x2go_listsessions_cache is not None:
+                    self.x2go_listsessions_cache.update_session_list(session_list=_listsessions)
 
-            _stdout_read = stdout.read()
-            _listsessions = self._list_backend(_stdout_read, info_backend=self._info_backend).sessions
-            if refresh_cache and self.x2go_listsessions_cache is not None:
-                self.x2go_listsessions_cache.update_session_list(session_list=_listsessions)
+                return _listsessions
 
-            return _listsessions
+            except X2goSessionException, e:
+                self.logger('encountered X2goSessionsException: %s' % str(e), loglevel=log.loglevel_ERROR)
+                self._X2goSessions__disconnect()
 
         else:
 
@@ -497,7 +515,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         _session_names = [ t.get_session_name() for t in self.associated_terminals.values() ]
         if session_name in _session_names:
 
-            self.logger('suspending associated terminal session: %s' % session_name, log.loglevel_DEBUG)
+            self.logger('suspending associated terminal session: %s' % session_name, loglevel=log.loglevel_DEBUG)
             (stdin, stdout, stderr) = self._x2go_exec_command("x2gosuspend-session %s" % session_name, loglevel=log.loglevel_DEBUG)
             dummy_stdout = stdout.read()
             dummy_stderr = stderr.read()
@@ -507,7 +525,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
 
         else:
 
-            self.logger('suspending non-associated terminal session: %s' % session_name, log.loglevel_DEBUG)
+            self.logger('suspending non-associated terminal session: %s' % session_name, loglevel=log.loglevel_DEBUG)
             (stdin, stdout, stderr) = self._x2go_exec_command("x2gosuspend-session %s" % session_name, loglevel=log.loglevel_DEBUG)
             dummy_stdout = stdout.read()
             dummy_stderr = stderr.read()
@@ -535,7 +553,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         _session_names = [ t.get_session_name() for t in self.associated_terminals.values() ]
         if session_name in _session_names:
 
-            self.logger('suspending associated session: %s' % session_name, log.loglevel_DEBUG)
+            self.logger('suspending associated session: %s' % session_name, loglevel=log.loglevel_DEBUG)
             (stdin, stdout, stderr) = self._x2go_exec_command("x2goterminate-session %s" % session_name, loglevel=log.loglevel_DEBUG)
             dummy_stdout = stdout.read()
             dummy_stderr = stderr.read()
@@ -547,7 +565,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
 
         else:
 
-            self.logger('suspending non-associated session: %s' % session_name, log.loglevel_DEBUG)
+            self.logger('suspending non-associated session: %s' % session_name, loglevel=log.loglevel_DEBUG)
             (stdin, stdout, stderr) = self._x2go_exec_command("x2goterminate-session %s" % session_name, loglevel=log.loglevel_DEBUG)
             dummy_stdout = stdout.read()
             dummy_stderr = stderr.read()
diff --git a/x2go/backends/profiles/https_broker.py b/x2go/backends/profiles/https_broker.py
index 7338f0f..6fcc4b7 100644
--- a/x2go/backends/profiles/https_broker.py
+++ b/x2go/backends/profiles/https_broker.py
@@ -39,7 +39,6 @@ from x2go.x2go_exceptions import X2goProfileException
 
 class X2goSessionProfilesHTTP(inifiles.X2goIniFile):
 
-    defaultValues = {}
     defaultSessionProfile = X2GO_SESSIONPROFILE_DEFAULTS
     _non_profile_sections = ('embedded')
 
@@ -48,6 +47,8 @@ class X2goSessionProfilesHTTP(inifiles.X2goIniFile):
         STILL UNDOCUMENTED
 
         """
+        self.defaultValues = {}
+
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
diff --git a/x2go/backends/profiles/sessions_file.py b/x2go/backends/profiles/sessions_file.py
index 3d0b7e9..4d1644b 100644
--- a/x2go/backends/profiles/sessions_file.py
+++ b/x2go/backends/profiles/sessions_file.py
@@ -39,7 +39,6 @@ from x2go.x2go_exceptions import X2goProfileException
 
 class X2goSessionProfilesFILE(inifiles.X2goIniFile):
 
-    defaultValues = {}
     defaultSessionProfile = X2GO_SESSIONPROFILE_DEFAULTS
     _non_profile_sections = ('embedded')
 
@@ -48,6 +47,8 @@ class X2goSessionProfilesFILE(inifiles.X2goIniFile):
         STILL UNDOCUMENTED
 
         """
+        self.defaultValues = {}
+
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
diff --git a/x2go/backends/profiles/win_registry.py b/x2go/backends/profiles/win_registry.py
index 247bd2b..86f8fe7 100644
--- a/x2go/backends/profiles/win_registry.py
+++ b/x2go/backends/profiles/win_registry.py
@@ -40,7 +40,6 @@ from x2go.x2go_exceptions import X2goProfileException
 
 class X2goSessionProfilesWINREG(inifiles.X2goIniFile):
 
-    defaultValues = {}
     defaultSessionProfile = X2GO_SESSIONPROFILE_DEFAULTS
     _non_profile_sections = ('embedded')
 
@@ -49,6 +48,8 @@ class X2goSessionProfilesWINREG(inifiles.X2goIniFile):
         STILL UNDOCUMENTED
 
         """
+        self.defaultValues = {}
+
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
diff --git a/x2go/backends/terminal/stdout.py b/x2go/backends/terminal/stdout.py
index 367a92b..5e0d259 100644
--- a/x2go/backends/terminal/stdout.py
+++ b/x2go/backends/terminal/stdout.py
@@ -192,19 +192,6 @@ class X2goTerminalSessionSTDOUT(object):
     @type loglevel: int
 
     """
-    params = None
-    session_info = None
-    control_session = None
-
-    proxy_class = None
-    proxy = None
-    proxy_subprocess = None
-
-    guardian_thread = None
-    reverse_tunnels = {}
-
-    print_queue = None
-
     def __init__(self, control_session, session_info=None,
                  geometry="800x600", depth=24, link="adsl", pack="16m-jpeg-9", 
                  cache_type="unix-kde", kblayout='us', kbtype='pc105/us',
@@ -222,6 +209,14 @@ class X2goTerminalSessionSTDOUT(object):
         currently running sessions on a connected X2go server.
 
         """
+        self.proxy = None
+        self.proxy_subprocess = None
+
+        self.guardian_thread = None
+        self.reverse_tunnels = {}
+
+        self.print_queue = None
+
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
@@ -423,7 +418,7 @@ class X2goTerminalSessionSTDOUT(object):
 
         """
         if self.session_info.username not in self.control_session._x2go_remote_group('x2goprint'):
-            raise x2go_exceptions.X2goPrintException('remote user %s is not member of X2go server group x2goprint' % self.session_info.username)
+            raise x2go_exceptions.X2goUserException('remote user %s is not member of X2go server group x2goprint' % self.session_info.username)
 
         spool_dir = os.path.join(self.session_info.local_container, 'spool')
         if not os.path.exists(spool_dir):
diff --git a/x2go/cache.py b/x2go/cache.py
index 147c5b4..b1e8e89 100644
--- a/x2go/cache.py
+++ b/x2go/cache.py
@@ -38,8 +38,6 @@ class X2goListSessionsCache(threading.Thread):
 
     """
 
-    x2go_listsessions_cache = None
-
     def __init__(self, control_session, refresh_interval=5, logger=None, loglevel=log.loglevel_DEFAULT):
         """\
         @param control: the L{X2goControlSession} that uses this L{X2goListSessionsCache}
@@ -53,6 +51,9 @@ class X2goListSessionsCache(threading.Thread):
         @type loglevel: C{int}
 
         """
+        self.x2go_listsessions_cache = None
+        self.last_listsessions_cache = None
+
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
@@ -60,6 +61,7 @@ class X2goListSessionsCache(threading.Thread):
         self.logger.tag = __NAME__
 
         self.control_session = control_session
+        self.last_sessionlist = None
         self.refresh_interval = refresh_interval
         threading.Thread.__init__(self, target=self.refresh_cache)
         self.daemon = True
@@ -75,6 +77,7 @@ class X2goListSessionsCache(threading.Thread):
             gevent.sleep(1)
             seconds += 1
             if seconds % self.refresh_interval == 0:
+                self.list_listsessions_cache = copy.deepcopy(self.x2go_listsessions_cache)
                 self.update_session_list()
 
     def update_session_list(self, session_list=None):
@@ -90,7 +93,9 @@ class X2goListSessionsCache(threading.Thread):
             try:
                 self.x2go_listsessions_cache = self.control_session.list_sessions(no_cache=True)
             except x2go_exceptions.X2goSessionException:
-                pass
+                for s in self.control_session.controlled_sessions.values():
+                    s.__hook_session_has_died()
+                    s._X2goSession__disconnect()
         else:
             self.x2go_listsessions_cache = session_list
 
diff --git a/x2go/client.py b/x2go/client.py
index ad329ac..c1ea7b2 100644
--- a/x2go/client.py
+++ b/x2go/client.py
@@ -125,6 +125,7 @@ import sys
 from settings import X2goClientSettings
 from printing import X2goClientPrinting
 from registry import X2goSessionRegistry
+from guardian import X2goSessionGuardian
 import log
 import utils
 
@@ -145,11 +146,6 @@ class X2goClient(object):
     session object etc.) and connected to it (authentication). For these two steps
     use these methods: L{X2goClient.register_session()} and L{X2goClient.connect_session()}.
     """
-    session_profiles = None
-    session_registry = None
-    client_settings = None
-    client_printing = None
-
     def __init__(self, logger=None, loglevel=log.loglevel_DEFAULT):
         """\
         @param logger: you can pass an L{X2goLogger} object to the
@@ -460,7 +456,7 @@ class X2goClient(object):
         """
         return self.session_registry(session_uuid).connect(username=username, password=password, 
                                                            add_to_known_hosts=add_to_known_hosts, 
-                                                           force_password_auth=force_password_auth
+                                                           force_password_auth=force_password_auth,
                                                           )
     __connect_session = connect_session
 
@@ -877,7 +873,7 @@ class X2goClient(object):
         return self.session_registry(session_uuid).is_alive()
     __server_is_alive = server_is_alive
 
-    def server_is_x2gouser(self, session_uuid, username=None):
+    def server_valid_x2gouser(self, session_uuid, username=None):
         """\
         Check if user is allowed to start an X2go session on a remote server.
 
@@ -885,8 +881,8 @@ class X2goClient(object):
         @rtype: C{str}
 
         """
-        return self.session_registry(session_uuid).is_x2gouser(username=None)
-    __server_is_x2gouser = server_is_x2gouser
+        return self.session_registry(session_uuid).user_is_x2gouser(username=username)
+    __server_valid_x2gouser = server_valid_x2gouser
 
     def server_running_sessions(self, session_uuid):
         """\
diff --git a/x2go/guardian.py b/x2go/guardian.py
index 7c483f6..176c274 100644
--- a/x2go/guardian.py
+++ b/x2go/guardian.py
@@ -67,6 +67,8 @@ class X2goSessionGuardian(threading.Thread):
         @type loglevel: C{int}
 
         """
+        self.active_threads = []
+
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
diff --git a/x2go/session.py b/x2go/session.py
index c842497..2c6129f 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -54,6 +54,14 @@ _X2GO_SESSION_PARAMS = ('geometry', 'depth', 'link', 'pack',
 
 class X2goSession(object):
 
+    # user hooks for detecting/notifying what happened with this session 
+    def __hook_session_has_died(self):
+        self.logger('the control session of session %s has unexpectedly died' % self.get_session_name())
+    def __hook_session_suspended(self):
+        self.logger('session %s has been suspended from within the application' % self.get_session_name())
+    def __hook_session_terminated(self):
+        self.logger('session %s has been terminated from within the application' % self.get_session_name())
+
     def __init__(self, server, control_session=None,
                  profile_id=None, profile_name=None,
                  printing=None, share_local_folders=[],
@@ -115,9 +123,11 @@ class X2goSession(object):
                                                    info_backend=info_backend,
                                                    list_backend=list_backend,
                                                    proxy_backend=proxy_backend,
+                                                   controlled_session=self,
                                                    logger=logger)
         else:
             self.control_session = control_session
+            self.control_session.controlled_sessions[self.get_uuid()] = self
 
         self.terminal_session = None
         self.guardian_thread = None
@@ -157,10 +167,11 @@ class X2goSession(object):
     __get_username = get_username
 
 
-    def is_x2gouser(self, username=None):
+    def user_is_x2gouser(self, username=None):
         if username is None:
-            username = self.get_username()
+            username = self.__get_username()
         return self.control_session.is_x2gouser(username)
+    __user_is_x2gouser = user_is_x2gouser
 
     def get_password(self):
         """\
@@ -209,6 +220,7 @@ class X2goSession(object):
         if self.terminal_params.has_key('cmd'):
             return self.terminal_params['cmd']
         return None
+    __get_session_cmd = get_session_cmd
 
     def get_control_session(self):
         """\
@@ -234,7 +246,7 @@ class X2goSession(object):
         return self.terminal_session is not None
     __has_terminal_session = has_terminal_session
 
-    def connect(self, username='', password='', add_to_known_hosts=False, force_password_auth=False):
+    def connect(self, username='', password='', add_to_known_hosts=None, force_password_auth=None):
         """\
         Connect to a registered X2go session with registry hash C{<session_uuid>}.
         This method basically wraps around paramiko.SSHClient.connect() for the
@@ -261,8 +273,14 @@ class X2goSession(object):
         else:
             if username:
                 self.control_params['username'] = username
+            if add_to_known_hosts is not None:
+                self.control_params['add_to_known_hosts'] = add_to_known_hosts
+            if force_password_auth is not None:
+                self.control_params['force_password_auth'] = force_password_auth
             self.control_params['password'] = password
-            self.connected = self.control_session.connect(self.server, **self.control_params)
+            self.connected = self.control_session.connect(self.server,
+                                                          **self.control_params
+                                                         )
         return self.connected
     __connect = connect
 
@@ -289,7 +307,10 @@ class X2goSession(object):
     __set_print_action = set_print_action
 
     def is_alive(self):
-        return self.control_session.is_alive()
+        _alive = self.control_session.is_alive()
+        if not _alive:
+            self.disconnect()
+        return _alive
     __is_alive = is_alive
 
     def clean_sessions(self):
@@ -330,7 +351,7 @@ class X2goSession(object):
                 try:
                     if SUPPORTED_PRINTING and self.printing:
                         _terminal.start_printing()
-                except X2goPrintException:
+                except X2goUserException:
                     pass
 
                 if SUPPORTED_FOLDERSHARING and self.share_local_folders:
diff --git a/x2go/x2go_exceptions.py b/x2go/x2go_exceptions.py
index 0d8ec8e..950a0c7 100644
--- a/x2go/x2go_exceptions.py
+++ b/x2go/x2go_exceptions.py
@@ -25,6 +25,7 @@ __NAME__ = 'x2goexceptions-pylib'
 
 # modules
 import paramiko
+import exceptions
 
 # Python X2go Exceptions
 AuthenticationException = paramiko.AuthenticationException
@@ -36,14 +37,11 @@ BadHostKeyException = paramiko.AuthenticationException
 SSHException = paramiko.SSHException
 """inherited from Python Paramiko library"""
 
-class _X2goException(Exception):
-    def __init__(self, value):
-        self.value = value
-    def __str__(self):
-        return repr(self.value)
-
+class _X2goException(exceptions.BaseException): pass
 class X2goClientException(_X2goException): pass
 class X2goSessionException(_X2goException): pass
+class X2goSessionException(_X2goException): pass
+class X2goUserException(_X2goException): pass
 class X2goProfileException(_X2goException): pass
 class X2goSettingsException(_X2goException): pass
 class X2goFwTunnelException(_X2goException): pass


hooks/post-receive
-- 
python-x2go.git (Python X2Go Client API)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-x2go.git" (Python X2Go Client API).




More information about the x2go-commits mailing list