[X2go-Commits] python-x2go.git - build-main (branch) updated: 0.2.0.2

X2Go dev team git-admin at x2go.org
Fri Jun 8 09:22:17 CEST 2012


The branch, build-main has been updated
       via  1e28d700dd71f9ff121f6ad702717020b95bade0 (commit)
       via  ccec42eda30c802ce9d777a3711750fe1ace2e2f (commit)
       via  907069213701818b0530242e7d735f6ad88347c2 (commit)
       via  cf525d5c61ed6c238174ab3a5141f72758883766 (commit)
       via  a58f12c5bbe45b817fd0b7a2e7105e3dcf5017c2 (commit)
       via  ab5473d6e4c446309c589f8f5f8413f320e87b7a (commit)
       via  699da4c0fe1a13fc8e0a4988360b4101348cce77 (commit)
       via  6184896fab1e7e2551f561e854db30e07d4ec032 (commit)
       via  0983bbcce7c7ff1cfd98b9dd96045607fc2a8a1d (commit)
       via  44542ee31e44307378364c316a0539341abd3a0d (commit)
       via  683be10d60d52c45a68f5dd4a852683533a5f3c9 (commit)
      from  3b29079cabb2be1405f78ffc2bd03af5db491966 (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:
 debian/changelog                  |   17 +++++-
 x2go/__init__.py                  |    2 +-
 x2go/backends/control/_stdout.py  |   63 ++++++++++++++++-------
 x2go/backends/terminal/_stdout.py |    5 ++
 x2go/cache.py                     |    9 +++-
 x2go/guardian.py                  |    1 -
 x2go/registry.py                  |    3 +-
 x2go/session.py                   |  101 ++++++++++++++++++++++++++++++++-----
 8 files changed, 163 insertions(+), 38 deletions(-)

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index fc90e52..aabb0d9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,19 @@
-python-x2go (0.2.0.2-0~x2go1) UNRELEASED; urgency=low
-
-  * Continue development...
-
- -- Mike Gabriel <mike.gabriel at das-netzwerkteam.de>  Wed, 30 May 2012 00:27:03 +0200
+python-x2go (0.2.0.2-0~x2go1) unstable; urgency=low
+
+  * Bugfix release (0.2.0.2):
+    - Be tolerant if we can not terminate a session after failure of the
+      forwarding tunnel.
+    - Improve session management, handle exceptions more gracefully.
+    - Ignoring timeouts for x2golistmounts and x2golistdesktops.
+    - Add support to X2goSession class to launch sessions from the Python
+      interactive shell in five steps.
+    - Mark sessions as dead whenever an X2goControlSessionException occurs.
+    - Catch control session deaths when querying X2goSession.is_alive().
+    - Do not create a high CPU load after a network failure, do not try to
+      execute a remote command if the session has already died away.
+    - The master_sessions dict may never have None values.
+
+ -- Mike Gabriel <mike.gabriel at das-netzwerkteam.de>  Fri, 08 Jun 2012 09:19:49 +0200
 
 python-x2go (0.2.0.1-0~x2go1) unstable; urgency=low
 
diff --git a/x2go/__init__.py b/x2go/__init__.py
index bc0a776..3420925 100644
--- a/x2go/__init__.py
+++ b/x2go/__init__.py
@@ -178,7 +178,7 @@ Contact
 """
 
 __NAME__    = 'python-x2go'
-__VERSION__ = '0.2.0.0'
+__VERSION__ = '0.2.0.2'
 
 from gevent import monkey
 monkey.patch_all()
diff --git a/x2go/backends/control/_stdout.py b/x2go/backends/control/_stdout.py
index a5c2fd6..05f355c 100644
--- a/x2go/backends/control/_stdout.py
+++ b/x2go/backends/control/_stdout.py
@@ -36,6 +36,7 @@ import random
 import re
 import locale
 import threading
+import cStringIO
 
 from gevent import socket
 
@@ -275,6 +276,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                 self.sftp_client.put(os.path.normpath(local_path), remote_path)
             except x2go_exceptions.SSHException, socket.error:
                 # react to connection dropped error for SSH connections
+                self.session_died = True
                 self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('The SSH connection was dropped during an sFTP put action.')
             self.sftp_client = None
@@ -305,6 +307,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                 remote_fileobj.write(content)
                 remote_fileobj.close()
             except x2go_exceptions.SSHException, socket.error:
+                self.session_died = True
                 self._transport_lock.release()
                 self.logger('sFTP-write: opening remote file %s on host %s failed' % (remote_path, self.remote_peername()), loglevel=log.loglevel_WARN)
                 raise x2go_exceptions.X2goControlSessionException('The SSH connection was dropped during an sFTP write action.')
@@ -331,6 +334,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
             try:
                 self.sftp_client.remove(remote_path)
             except x2go_exceptions.SSHException, socket.error:
+                self.session_died = True
                 self._transport_lock.release()
                 self.logger('sFTP-write: removing remote file %s on host %s failed' % (remote_path, self.remote_peername()), loglevel=log.loglevel_WARN)
                 raise x2go_exceptions.X2goControlSessionException('The SSH connection was dropped during an sFTP remove action.')
@@ -359,51 +363,56 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         @raise X2goControlSessionException: if the command execution failed (due to a lost connection)
 
         """
-        self._transport_lock.acquire()
-
-        _retval = None
-
         if type(cmd_line) == types.ListType:
             cmd = " ".join(cmd_line)
         else:
             cmd = cmd_line
+
+        if self.session_died:
+            self.logger("control session seams to be dead, not executing command ,,%s'' on X2Go server %s" % (_rerewrite_blanks(cmd), self.profile_name,), loglevel=loglevel)
+            return (cStringIO.StringIO(), cStringIO.StringIO(), cStringIO.StringIO('failed to execute command'))
+
+        self._transport_lock.acquire()
+
+        _retval = None
+
         ssh_transport = self.get_transport()
         if ssh_transport and ssh_transport.is_authenticated():
 
             timer = gevent.Timeout(timeout)
             timer.start()
             try:
-                self.logger("executing command on X2Go server ,,%s'': %s" % (self.profile_name, _rerewrite_blanks(cmd)), loglevel)
+                self.logger("executing command on X2Go server ,,%s'': %s" % (self.profile_name, _rerewrite_blanks(cmd)), loglevel=loglevel)
                 _retval = self.exec_command(_rewrite_password(cmd, user=self.get_transport().get_username(), password=self._session_password), **kwargs)
             except AttributeError:
                 self.session_died = True
+                self._transport_lock.release()
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             except EOFError:
                 self.session_died = True
+                self._transport_lock.release()
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             except x2go_exceptions.SSHException:
                 self.session_died = True
+                self._transport_lock.release()
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             except gevent.timeout.Timeout:
                 self.session_died = True
+                self._transport_lock.release()
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session command timed out')
             except socket.error:
                 self.session_died = True
+                self._transport_lock.release()
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             finally:
                 timer.cancel()
@@ -521,6 +530,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                 try:
                     self._remote_username = self.get_transport().get_username()
                 except:
+                    self.session_died = True
                     raise x2go_exceptions.X2goControlSessionException('Lost connection to X2Go server')
         return self._remote_username
 
@@ -539,6 +549,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                 try:
                     self._remote_peername = self.get_transport().getpeername()
                 except:
+                    self.session_died = True
                     raise x2go_exceptions.X2goControlSessionException('Lost connection to X2Go server')
         return self._remote_peername
 
@@ -842,7 +853,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                 except x2go_exceptions.X2goTerminalSessionException:
                     pass
                 except x2go_exceptions.X2goControlSessionException:
-                    pass
+                    self.session_died
                 t_obj.__del__()
             for t_name in t_names:
                 try:
@@ -896,10 +907,23 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         @rtype: C{bool}
 
         """
-        if self._x2go_exec_command('echo', loglevel=log.loglevel_DEBUG):
-            return True
+        try:
+            if self._x2go_exec_command('echo', loglevel=log.loglevel_DEBUG):
+                return True
+        except x2go_exceptions.X2goControlSessionException:
+            self.session_died = True
         return False
 
+    def has_session_died(self):
+        """\
+        Test if the connection to the remote X2Go server died on the way.
+
+        @return: C{True} if the connection has died, C{False} otherwise
+        @rtype: C{bool}
+
+        """
+        return self.session_died
+
     def get_published_applications(self, lang=None, refresh=False, raw=False, very_raw=False, max_no_submenus=defaults.PUBAPP_MAX_NO_SUBMENUS):
         """\
         Retrieve the menu tree of published applications from the remote X2Go server.
@@ -1158,11 +1182,13 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                                            **kwargs)
 
         _success = False
-        if session_name is not None:
-            _success = _terminal.resume()
-
-        else:
-            _success = _terminal.start()
+        try:
+            if session_name is not None:
+                _success = _terminal.resume()
+            else:
+                _success = _terminal.start()
+        except x2go_exceptions.X2goTerminalSessionException:
+            _success = False
 
         if _success:
             while not _terminal.ok():
@@ -1345,6 +1371,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                     gevent.sleep(1)
 
             if _count >= _maxwait:
+                self.session_died = True
                 raise x2go_exceptions.X2goControlSessionException('x2golistsessions command failed after we have tried 20 times')
 
             # update internal variables when list_sessions() is called
diff --git a/x2go/backends/terminal/_stdout.py b/x2go/backends/terminal/_stdout.py
index b1f1259..bcd6771 100644
--- a/x2go/backends/terminal/_stdout.py
+++ b/x2go/backends/terminal/_stdout.py
@@ -1440,6 +1440,9 @@ class X2goTerminalSessionSTDOUT(object):
             if self.params.published_applications:
                 self.control_session.get_published_applications()
 
+        else:
+            raise x2go_exceptions.X2goTerminalSessionException("failed to start X2Go session")
+
         return proxy_ok
 
     def resume(self):
@@ -1524,6 +1527,8 @@ class X2goTerminalSessionSTDOUT(object):
             if self.is_published_applications_provider():
                 self.control_session.get_published_applications()
                 self.published_applications = True
+        else:
+            raise x2go_exceptions.X2goTerminalSessionException("failed to start X2Go session")
 
         return proxy_ok
 
diff --git a/x2go/cache.py b/x2go/cache.py
index 2b6f9ec..5d90191 100644
--- a/x2go/cache.py
+++ b/x2go/cache.py
@@ -82,7 +82,7 @@ class X2goListSessionsCache(object):
 
         """
         while self.protected:
-            gevent.sleep()
+            gevent.sleep(.1)
         try: del self.x2go_listsessions_cache[profile_name]
         except KeyError: pass
 
@@ -155,7 +155,10 @@ class X2goListSessionsCache(object):
         except x2go_exceptions.X2goControlSessionException, e:
             if profile_name in self.x2go_listsessions_cache.keys():
                 del self.x2go_listsessions_cache[profile_name]
+            self.protected = False
             raise e
+        except x2go_exceptions.X2goTimeOutException:
+            pass
 
     def _update_desktops(self, profile_name, control_session):
         """\
@@ -173,7 +176,10 @@ class X2goListSessionsCache(object):
         except x2go_exceptions.X2goControlSessionException, e:
             if profile_name in self.x2go_listsessions_cache.keys():
                 del self.x2go_listsessions_cache[profile_name]
+            self.protected = False
             raise e
+        except x2go_exceptions.X2goTimeOutException:
+            pass
 
     def _update_sessions(self, profile_name, control_session):
         """\
@@ -190,6 +196,7 @@ class X2goListSessionsCache(object):
         except x2go_exceptions.X2goControlSessionException, e:
             if profile_name in self.x2go_listsessions_cache.keys():
                 del self.x2go_listsessions_cache[profile_name]
+            self.protected = False
             raise e
 
     def list_sessions(self, session_uuid):
diff --git a/x2go/guardian.py b/x2go/guardian.py
index 927811d..ba5d5b2 100644
--- a/x2go/guardian.py
+++ b/x2go/guardian.py
@@ -106,7 +106,6 @@ class X2goSessionGuardian(threading.Thread):
 
                 self.logger('Entering X2Go Guardian client management loop...', loglevel=log.loglevel_DEBUG)
 
-
                 if self.auto_update_listsessions_cache:
                     self.client_instance.update_cache_all_profiles(update_sessions=self.auto_update_listsessions_cache, 
                                                                    update_desktops=self.auto_update_listdesktops_cache,
diff --git a/x2go/registry.py b/x2go/registry.py
index f9bf5ad..85ddf3f 100644
--- a/x2go/registry.py
+++ b/x2go/registry.py
@@ -1047,7 +1047,8 @@ class X2goSessionRegistry(object):
         _session = self.master_sessions[profile_name]
 
         if not _session.is_master_session():
-            self.master_sessions[profile_name] = None
+            del self.master_sessions[profile_name]
+            return None
 
         if return_object:
             return _session
diff --git a/x2go/session.py b/x2go/session.py
index ae92272..9368d96 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -25,7 +25,30 @@ This class is normally embedded into the context of an L{X2goClient}
 instance, but it is also possible to address L{X2goSession}s directly via this
 class.
 
+To launch a session manually from the Python interactive shell, perform these
+simple steps::
+
+  $ python
+  Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
+  [GCC 4.4.5] on linux2
+  Type "help", "copyright", "credits" or "license" for more information.
+  >>> import x2go
+  >>> import gevent
+  Xlib.protocol.request.QueryExtension
+  >>> s = x2go.session.X2goSession()
+  >>> s.set_server('<my.x2go.server>')
+  >>> s.set_port(<ssh-port>)
+  >>> s.connect('<my-login>', '<my-password>')
+  [<pidno>] (x2gocontrolsession-pylib) NOTICE: connecting to [<my.x2go.server>]:<ssh-port>
+  [<pidno>] (x2gosession-pylib) NOTICE: SSH host key verification for host [<my.x2go.server>]:<ssh-port> with SSH-RSA fingerprint ,,<ssh-fingerprint>'' initiated. We are seeing this X2Go server for the first time.
+  [<pidno>] (x2gosession-pylib) WARN: HOOK_check_host_dialog: host check requested for [<my.x2go.server>]:<ssh-port> with SSH-RSA fingerprint: ,,<ssh-fingerprint>''. Automatically adding host as known host.
+  True
+  >>> s.start(cmd="LXDE")
+  True
+  >>> while True: gevent.sleep(1)
+
 """
+
 __NAME__ = 'x2gosession-pylib'
 
 import os
@@ -105,7 +128,7 @@ class X2goSession(object):
     sessions etc.).
 
     """
-    def __init__(self, server=None, control_session=None,
+    def __init__(self, server=None, port=22, control_session=None,
                  use_sshproxy=False,
                  profile_id=None, profile_name='UNKNOWN',
                  session_name=None,
@@ -232,6 +255,7 @@ class X2goSession(object):
         self.profile_name = profile_name
         self.session_name = session_name
         self.server = server
+        self.port = port
 
         self._last_status = None
 
@@ -334,6 +358,19 @@ class X2goSession(object):
         """
         return self.client_instance
 
+    def HOOK_on_control_session_death(self):
+        """\
+        HOOK method: called if a control session (server connection) has unexpectedly encountered a failure.
+
+        @param profile_name: profile name of session that called this hook method
+        @type profile_name: C{str}
+
+        """
+        if self.client_instance:
+            self.client_instance.HOOK_on_control_session_death(profile_name=self.profile_name)
+        else:
+            self.logger('HOOK_on_control_session_death: the control session of profile %s has died unexpectedly' % self.profile_name, loglevel=log.loglevel_WARN)
+
     def HOOK_auto_connect(self):
         """\
         HOOK method: called if the session demands to auto connect.
@@ -342,7 +379,7 @@ class X2goSession(object):
         if self.client_instance:
             self.client_instance.HOOK_profile_auto_connect(profile_name=self.profile_name)
         else:
-            self.logger('HOOK_auto_connect: profile ,,%s'' wants to auto-connect to the X2Go server.' % self.profile_name, loglevel=log.loglevel_WARN)
+            self.logger('HOOK_auto_connect: profile ,,%s\'\' wants to auto-connect to the X2Go server.' % self.profile_name, loglevel=log.loglevel_WARN)
 
     def HOOK_session_startup_failed(self):
         """\
@@ -352,7 +389,7 @@ class X2goSession(object):
         if self.client_instance:
             self.client_instance.HOOK_session_startup_failed(profile_name=self.profile_name)
         else:
-            self.logger('HOOK_session_startup_failed: session startup for session profile ,,%s'' failed.' % self.profile_name, loglevel=log.loglevel_WARN)
+            self.logger('HOOK_session_startup_failed: session startup for session profile ,,%s\'\' failed.' % self.profile_name, loglevel=log.loglevel_WARN)
 
     def HOOK_rforward_request_denied(self, server_port=0):
         """\
@@ -386,7 +423,10 @@ class X2goSession(object):
             self.logger('HOOK_forwarding_tunnel_setup_failed: Forwarding tunnel request to [%s]:%s for session %s (%s) was denied by remote X2go/SSH server. Session startup failed.' % (chain_host, chain_port, self.session_name, self.profile_name), loglevel=log.loglevel_WARN)
 
         # get rid of the faulty session...
-        self.terminate()
+        try:
+            self.terminate()
+        except x2go_exceptions.X2goSessionException:
+            pass
 
     def HOOK_printing_not_available(self):
         """\
@@ -447,7 +487,7 @@ class X2goSession(object):
         if self.client_instance:
             return self.client_instance.HOOK_check_host_dialog(profile_name=self.profile_name, host=host, port=port, fingerprint=fingerprint, fingerprint_type=fingerprint_type)
         else:
-            self.logger('HOOK_check_host_dialog: host check requested for [%s]:%s with %s fingerprint: ,,%s.\'\'. Automatically adding host as known host.' % (host, port, fingerprint_type, fingerprint), loglevel=log.loglevel_WARN)
+            self.logger('HOOK_check_host_dialog: host check requested for [%s]:%s with %s fingerprint: ,,%s\'\'. Automatically adding host as known host.' % (host, port, fingerprint_type, fingerprint), loglevel=log.loglevel_WARN)
             return True
 
     def init_control_session(self):
@@ -483,9 +523,9 @@ class X2goSession(object):
         @rtype: C{bool}
 
         """
-        if self.master_session is None:
+        if self.master_session is None and self.client_instance is None:
             return True
-        return self.master_session
+        return bool(self.master_session)
 
     def set_master_session(self, wait=0, max_wait=20):
         """\
@@ -536,6 +576,16 @@ class X2goSession(object):
         """
         self.server = server
 
+    def set_port(self, port):
+        """\
+        Modify server port after L{X2goSession} has already been initialized.
+
+        @param port: socket port of server to connect to
+        @type port: C{int}
+
+        """
+        self.port = port
+
     def set_profile_name(self, profile_name):
         """\
         Modify session profile name after L{X2goSession} has already been initialized.
@@ -613,8 +663,6 @@ class X2goSession(object):
                 self.get_control_session().__del__()
                 self.control_session = None
 
-        self.master_session = None
-
         if self.has_terminal_session():
             self.get_terminal_session().__del__()
             self.terminal_session = None
@@ -1060,6 +1108,9 @@ class X2goSession(object):
             _params.update(self.control_params)
             _params.update(self.sshproxy_params)
 
+            if 'port' not in _params:
+                _params['port'] = self.port
+
             try:
                 self.connected = self.control_session.connect(self.server,
                                                               use_sshproxy=self.use_sshproxy, 
@@ -1110,7 +1161,8 @@ class X2goSession(object):
         self.suspended = None
         self.terminated = None
         self.faults = None
-        self.master_session = None
+        self.active = False
+        self.unset_master_session()
         try:
             self.update_status(force_update=True)
         except x2go_exceptions.X2goControlSessionException:
@@ -1201,6 +1253,8 @@ class X2goSession(object):
 
         """
         self.connected = self.control_session.is_alive()
+        if self.control_session.has_session_died():
+            self.HOOK_on_control_session_death()
         if not self.connected:
             self._X2goSession__disconnect()
         return self.connected
@@ -1242,6 +1296,7 @@ class X2goSession(object):
         try:
             return self.control_session.list_sessions(raw=raw)
         except x2go_exceptions.X2goControlSessionException:
+            self.HOOK_on_control_session_death()
             self._X2goSession__disconnect()
             return None
     __list_sessions = list_sessions
@@ -1261,6 +1316,7 @@ class X2goSession(object):
         try:
             return self.control_session.list_desktops(raw=raw)
         except x2go_exceptions.X2goControlSessionException:
+            self.HOOK_on_control_session_death()
             self._X2goSession__disconnect()
             return None
     __list_desktops = list_desktops
@@ -1281,6 +1337,7 @@ class X2goSession(object):
         try:
             return self.control_session.list_mounts(self.session_name, raw=raw)
         except x2go_exceptions.X2goControlSessionException:
+            self.HOOK_on_control_session_death()
             self._X2goSession__disconnect()
             return None
 
@@ -1472,7 +1529,7 @@ class X2goSession(object):
                     if not self.published_applications:
                         return self.start()
 
-    def resume(self, session_name=None, session_list=None):
+    def resume(self, session_name=None, session_list=None, cmd=None):
         """\
         Resume or continue a suspended / running X2Go session on the
         remote X2Go server.
@@ -1481,6 +1538,9 @@ class X2goSession(object):
         @type session_name: C{str}
         @param session_list: a session list to avoid a server-side session list query
         @type session_list: C{dict}
+        @param cmd: if starting a new session, manually hand over the command to be launched in
+            the new session
+        @type cmd: C{str}
 
         @return: returns C{True} if resuming the session has been successful, C{False} otherwise
         @rtype: C{bool}
@@ -1515,6 +1575,9 @@ class X2goSession(object):
                 # FIXME: test the code to see what exceptions may occur here...
                 raise
 
+            if cmd is not None:
+                self.terminal_params['cmd'] = cmd
+
             self.terminal_session = _control.resume(session_name=self.session_name,
                                                     session_instance=self,
                                                     session_list=session_list,
@@ -1525,6 +1588,7 @@ class X2goSession(object):
                 try:
                     self.session_name = self.terminal_session.session_info.name
                 except AttributeError:
+                    # if self.terminal_session is None, we end up with a session failure...
                     self.HOOK_session_startup_failed()
                     return False
 
@@ -1600,16 +1664,19 @@ class X2goSession(object):
 
     __resume = resume
 
-    def start(self):
+    def start(self, cmd=None):
         """\
         Start a new X2Go session on the remote X2Go server.
 
+        @param cmd: manually hand over the command that is to be launched in the new session
+        @type cmd: C{str}
+
         @return: returns C{True} if starting the session has been successful, C{False} otherwise
         @rtype: C{bool}
 
         """
         self.session_name = None
-        return self.resume()
+        return self.resume(cmd=cmd)
     __start = start
 
     def share_desktop(self, desktop=None, user=None, display=None, share_mode=0, check_desktop_list=True):
@@ -1705,10 +1772,13 @@ class X2goSession(object):
                 self.suspended = True
                 self.terminated = False
                 self.faulty = False
+                self.active = False
 
                 # unmount shared folders
                 self.unshare_all_local_folders(force_all=True)
 
+                self.unset_master_session()
+
                 if self.terminal_session.suspend():
 
                     self.session_cleanup()
@@ -1723,6 +1793,7 @@ class X2goSession(object):
                     self.suspended = True
                     self.terminated = False
                     self.faulty = False
+                    self.active = False
                     self.session_cleanup()
                     return True
 
@@ -1752,10 +1823,13 @@ class X2goSession(object):
                 self.suspended = False
                 self.terminated = True
                 self.faulty = False
+                self.active = False
 
                 # unmount shared folders
                 self.unshare_all_local_folders(force_all=True)
 
+                self.unset_master_session()
+
                 if self.terminal_session.terminate():
                     self.session_cleanup()
                     del self.terminal_session
@@ -1769,6 +1843,7 @@ class X2goSession(object):
                     self.suspended = False
                     self.terminated = True
                     self.faulty = False
+                    self.active = False
                     self.session_cleanup()
                     return True
             else:


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