[X2Go-Commits] python-x2go.git - build-baikal (branch) updated: 0.1.1.4-136-gb190513

X2Go dev team git-admin at x2go.org
Wed Jan 8 15:30:53 CET 2014


The branch, build-baikal has been updated
       via  b19051303645f8c5fe8448ee289273698b538212 (commit)
      from  93a1d5c37c65e15b75407a935e84b62f9196f2fd (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  |   16 ++++++--
 x2go/backends/info/_stdout.py     |   30 ++++++++++++++
 x2go/backends/terminal/_stdout.py |   41 ++++++++++++++++++-
 x2go/client.py                    |    3 +-
 x2go/registry.py                  |   80 ++++++++++++++++++++++---------------
 x2go/session.py                   |   69 ++++++++++++++++++++++----------
 6 files changed, 178 insertions(+), 61 deletions(-)

The diff of changes is:
diff --git a/x2go/backends/control/_stdout.py b/x2go/backends/control/_stdout.py
index f4c67d0..b04dda3 100644
--- a/x2go/backends/control/_stdout.py
+++ b/x2go/backends/control/_stdout.py
@@ -167,7 +167,11 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
     def _x2go_sftp_put(self, local_path, remote_path):
 
         self.logger('sFTP-put: %s -> %s:%s' % (os.path.normpath(local_path), self.get_transport().getpeername(), remote_path), loglevel=log.loglevel_DEBUG)
-        self.sftp_client.put(os.path.normpath(local_path), remote_path)
+        try:
+            self.sftp_client.put(os.path.normpath(local_path), remote_path)
+        except SSHException:
+            # react to connection dropped error for SSH connections
+            raise x2go_exceptions.X2goControlSessionException('The SSH connection was dropped during an SFTP put action.')
 
     def _x2go_sftp_write(self, remote_path, content):
 
@@ -852,11 +856,15 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                 raise x2go_exceptions.X2goControlSessionException('x2golistsessions command failed after we have tried 20 times')
 
             # update internal variables when list_sessions() is called
-            for _session_name, _session_info in self.associated_terminals.items():
-                if _session_name not in _listsessions.keys():
+            for _session_name, _terminal in self.associated_terminals.items():
+                if _session_name in _listsessions.keys():
+                    # update the whole session_info object within the terminal session
+                    if hasattr(self.associated_terminals[_session_name], 'session_info') and not self.associated_terminals[_session_name].is_session_info_protected():
+                        self.associated_terminals[_session_name].session_info.update(_listsessions[_session_name])
+                else:
                     del self.associated_terminals[_session_name]
                     self.terminated_terminals.append(_session_name)
-                elif _session_info.is_suspended():
+                if _terminal.is_suspended():
                     del self.associated_terminals[_session_name]
 
             return _listsessions
diff --git a/x2go/backends/info/_stdout.py b/x2go/backends/info/_stdout.py
index c316ec7..2e7a8e2 100644
--- a/x2go/backends/info/_stdout.py
+++ b/x2go/backends/info/_stdout.py
@@ -32,6 +32,7 @@ __NAME__ = 'x2goserversessioninfo-pylib'
 import types
 import re
 
+import x2go.defaults as defaults
 
 class X2goServerSessionInfoSTDOUT(object):
     """\
@@ -96,6 +97,12 @@ class X2goServerSessionInfoSTDOUT(object):
 
         return self.status == 'S'
 
+    def is_desktop_session(self):
+
+        _desktop_sessions = defaults.X2GO_DESKTOPSESSIONS.keys()
+        _regexp_desktop_sessions = '(%s)' % "|".join(_desktop_sessions)
+        return re.match('.*_stD%s_.*' % _regexp_desktop_sessions, self.name)
+
     def _parse_x2gostartagent_output(self, x2go_output):
         """\
         Parse x2gostartagent output.
@@ -150,12 +157,22 @@ class X2goServerSessionInfoSTDOUT(object):
         @type remote_container: str
 
         """
+        self.protect()
         self._parse_x2gostartagent_output(x2go_output)
         self.username = username
         self.hostname = hostname
         self.local_container = local_container
         self.remote_container = remote_container
 
+    def protect(self):
+        self.protected = True
+
+    def unprotect(self):
+        self.protected = False
+
+    def is_protected(self):
+        return self.protected
+
     def clear(self):
         """\
         Clear all properties of a L{X2goServerSessionInfo} object.
@@ -176,6 +193,19 @@ class X2goServerSessionInfoSTDOUT(object):
         self.local_container = ''
         self.remote_container = ''
 
+    def update(self, session_info):
+        """\
+        Clear all properties of a L{X2goServerSessionInfo} object.
+
+        """
+        if type(session_info) == type(self):
+            for prop in ('graphics_port', 'snd_port', 'sshfs_port', 'date_suspended', 'status', ):
+                if hasattr(session_info, prop):
+                    _new = getattr(session_info, prop)
+                    _current = getattr(self, prop)
+                    if _new != _current:
+                        setattr(self, prop, _new)
+
     __init__ = clear
 
 
diff --git a/x2go/backends/terminal/_stdout.py b/x2go/backends/terminal/_stdout.py
index 4a38010..2155d2c 100644
--- a/x2go/backends/terminal/_stdout.py
+++ b/x2go/backends/terminal/_stdout.py
@@ -604,10 +604,33 @@ class X2goTerminalSessionSTDOUT(object):
         """\
         Return the server-side mimebox spooldir path.
 
-
         """
         return '%s/%s' % (self.session_info.remote_container, 'mimebox')
 
+    def is_session_info_protected(self):
+        """\
+        Test if this terminal's session info object is write-protected.
+
+        @return: Boolean expression for being read-only or read-write.
+        @rtype: C{bool}
+
+        """
+        self.session_info.is_protected()
+
+    def session_info_protect(self):
+        """\
+        Protect this terminal session's info object against updates.
+
+        """
+        self.session_info.protect()
+
+    def session_info_unprotect(self):
+        """\
+        Allow session info updates from within the list_sessions method of the control session.
+
+        """
+        self.session_info.unprotect()
+
     def share_local_folder(self, local_path=None, folder_type='disk'):
         """\
         Share a local folder with the X2Go session.
@@ -710,6 +733,7 @@ class X2goTerminalSessionSTDOUT(object):
         (stdin, stdout, stderr) = self.control_session._x2go_exec_command(cmd_line)
         _stdout = stdout.read().split('\n')
         self.logger('x2gomountdirs output is : %s' % _stdout, log.loglevel_NOTICE)
+
         if len(_stdout) >= 6 and _stdout[5].endswith('ok'):
             return True
         return False
@@ -973,6 +997,18 @@ class X2goTerminalSessionSTDOUT(object):
 
         return stdout.read(), stderr.read()
 
+    def is_desktop_session(self):
+        """\
+        Returns true if this session is a desktop session.
+
+        @return: Returns C{True} is this session is a desktop session.
+        @rtype: C{bool}
+
+        """
+        if self.session_info:
+            return self.session_info.is_desktop_session()
+        return False
+
     def is_published_applications_provider(self):
         """\
         Returns true if this session runs in published applications mode.
@@ -1008,7 +1044,8 @@ class X2goTerminalSessionSTDOUT(object):
         @rtype: bool
 
         """
-        return bool(self.session_info.name and self.proxy.ok())
+        _ok = bool(self.session_info.name and self.proxy.ok())
+        return _ok
 
     def is_running(self):
         """\
diff --git a/x2go/client.py b/x2go/client.py
index 4ff1e26..5201aca 100644
--- a/x2go/client.py
+++ b/x2go/client.py
@@ -1756,7 +1756,7 @@ class X2goClient(object):
         @rtype: C{list}
 
         """
-        return self.session_registry.master_session(profile_name, return_object=return_object, return_session_name=return_session_name)
+        return self.session_registry.get_master_session(profile_name, return_object=return_object, return_session_name=return_session_name)
     profile_master_session = get_master_session
     __get_master_session = get_master_session
     __profile_master_session = profile_master_session
@@ -2364,6 +2364,7 @@ class X2goClient(object):
             _list_mounts = {}
             for session in sessions:
                 _list_mounts.update(self.__list_mounts(session_uuid=session(), no_cache=no_cache, refresh_cache=refresh_cache, raw=False))
+        print _list_mounts
         return _list_mounts
 
     def list_mounts(self, session_uuid=None, 
diff --git a/x2go/registry.py b/x2go/registry.py
index 18b4d61..597d6cb 100644
--- a/x2go/registry.py
+++ b/x2go/registry.py
@@ -249,6 +249,10 @@ class X2goSessionRegistry(object):
 
         for _session_uuid in session_uuids:
 
+            # only operate on instantiated X2goSession objects
+            if type(self(_session_uuid)) != session.X2goSession:
+                continue
+
             if not self(_session_uuid).update_status(session_list=session_list, force_update=force_update):
                 # skip this run, as nothing has changed since the last time...
                 return False
@@ -283,10 +287,11 @@ class X2goSessionRegistry(object):
                             self.master_sessions[_profile_name] = self(_session_uuid)
                             self(_session_uuid).set_master_session()
 
-                        elif self(_session_uuid).published_applications:
-                            self(self.master_sessions[_profile_name]()).unset_master_session()
-                            self.master_sessions[_profile_name] = self(_session_uuid)
-                            self(_session_uuid).set_master_session()
+                        elif (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_desktop_session()) or \
+                             (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_published_applications_provider()):
+                                self(self.master_sessions[_profile_name]()).unset_master_session()
+                                self.master_sessions[_profile_name] = self(_session_uuid)
+                                self(_session_uuid).set_master_session()
 
                         if _last_status['suspended']:
                             # from a suspended state
@@ -332,15 +337,23 @@ class X2goSessionRegistry(object):
                 if len(self.virgin_sessions_of_profile_name(profile_name)) > 1:
                     self.forget(_session_uuid)
 
+        # detect master sessions for connected profiles that have lost (suspend/terminate) their master session or never had a master session
         for _profile_name in [ p for p in self.connected_profiles(return_profile_names=True) if p not in self.master_sessions.keys() ]:
             _running_associated_sessions = [ _s for _s in self.running_sessions_of_profile_name(_profile_name, return_objects=True) if _s.is_associated() ]
-            _pubapp_sessions = [ _s for _s in self.pubapp_sessions_of_profile_name(_profile_name, return_objects=True) if _s in _running_associated_sessions ]
-            if _pubapp_sessions:
-                self.master_sessions[_profile_name] = _pubapp_sessions[0]
-                _pubapp_sessions[0].set_master_session()
-            elif _running_associated_sessions:
-                self.master_sessions[_profile_name] = _running_associated_sessions[0]
-                _running_associated_sessions[0].set_master_session()
+            if _running_associated_sessions:
+                for _r_a_s in _running_associated_sessions:
+                    if _r_a_s.is_desktop_session():
+                        self.master_sessions[_profile_name] = _r_a_s
+                        _r_a_s.set_master_session()
+                        break
+                if not self.master_sessions.has_key(_profile_name):
+                    _pubapp_associated_sessions = self.pubapp_sessions_of_profile_name(_profile_name, return_objects=True)
+                    if _pubapp_associated_sessions:
+                        self.master_sessions[_profile_name] = _pubapp_associated_sessions[0]
+                        _pubapp_associated_sessions[0].set_master_session()
+                    else:
+                        self.master_sessions[_profile_name] = _running_associated_sessions[0]
+                        _running_associated_sessions[0].set_master_session()
 
         return True
 
@@ -786,11 +799,11 @@ class X2goSessionRegistry(object):
 
         """
         if return_objects:
-            return self.connected_sessions() and [ s for s in self.connected_sessions() if s.profile_name == profile_name ]
+            return self.connected_sessions() and [ s for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
         elif return_session_names:
-            return self.connected_sessions() and [ s.session_name for s in self.connected_sessions() if s.profile_name == profile_name ]
+            return self.connected_sessions() and [ s.session_name for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
         else:
-            return self.connected_sessions() and [ s.get_uuid() for s in self.connected_sessions() if s.profile_name == profile_name ]
+            return self.connected_sessions() and [ s.get_uuid() for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
 
     def associated_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
         """\
@@ -807,12 +820,13 @@ class X2goSessionRegistry(object):
         @rtype: C{list}
 
         """
+        print [ s.get_session_name()  for s in self.associated_sessions()]
         if return_objects:
-            return self.associated_sessions() and [ s for s in self.associated_sessions() if s.profile_name == profile_name ]
+            return self.associated_sessions() and [ s for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
         elif return_session_names:
-            return self.associated_sessions() and [ s.session_name for s in self.associated_sessions() if s.profile_name == profile_name ]
+            return self.associated_sessions() and [ s.session_name for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
         else:
-            return self.associated_sessions() and [ s.get_uuid() for s in self.associated_sessions() if s.profile_name == profile_name ]
+            return self.associated_sessions() and [ s.get_uuid() for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
 
     def pubapp_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
         """\
@@ -830,11 +844,11 @@ class X2goSessionRegistry(object):
 
         """
         if return_objects:
-            return self.associated_sessions() and [ s for s in self.associated_sessions() if s.published_applications ]
+            return self.associated_sessions_of_profile_name(profile_name) and [ s for s in self.associated_sessions_of_profile_name(profile_name) if s.is_published_applications_provider() ]
         elif return_session_names:
-            return self.associated_sessions() and [ s.session_name for s in self.associated_sessions() if s.published_applications ]
+            return self.associated_sessions_of_profile_name(profile_name) and [ s.session_name for s in self.associated_sessions_of_profile_name(profile_name) if s.is_published_applications_provider() ]
         else:
-            return self.associated_sessions() and [ s.get_uuid() for s in self.associated_sessions() if s.published_applications ]
+            return self.associated_sessions_of_profile_name(profile_name) and [ s.get_uuid() for s in self.associated_sessions_of_profile_name(profile_name) if s.is_published_applications_provider() ]
 
     def registered_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
         """\
@@ -853,11 +867,11 @@ class X2goSessionRegistry(object):
         """
 
         if return_objects:
-            return self.registered_sessions() and [ s for s in self.registered_sessions() if s.profile_name == profile_name ]
+            return self.registered_sessions() and [ s for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
         elif return_session_names:
-            return self.registered_sessions() and [ s.session_name for s in self.registered_sessions() if s.profile_name == profile_name ]
+            return self.registered_sessions() and [ s.session_name for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
         else:
-            return self.registered_sessions() and [ s.get_uuid() for s in self.registered_sessions() if s.profile_name == profile_name ]
+            return self.registered_sessions() and [ s.get_uuid() for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
 
     def virgin_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
         """\
@@ -876,11 +890,11 @@ class X2goSessionRegistry(object):
 
         """
         if return_objects:
-            return self.virgin_sessions() and [ s for s in self.virgin_sessions() if s.profile_name == profile_name ]
+            return self.virgin_sessions() and [ s for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
         elif return_session_names:
-            return self.virgin_sessions() and [ s.session_name for s in self.virgin_sessions() if s.profile_name == profile_name ]
+            return self.virgin_sessions() and [ s.session_name for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
         else:
-            return self.virgin_sessions() and [ s.get_uuid() for s in self.virgin_sessions() if s.profile_name == profile_name ]
+            return self.virgin_sessions() and [ s.get_uuid() for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
 
     def running_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
         """\
@@ -898,11 +912,11 @@ class X2goSessionRegistry(object):
 
         """
         if return_objects:
-            return self.running_sessions() and [ s for s in self.running_sessions() if s.profile_name == profile_name ]
+            return self.running_sessions() and [ s for s in self.running_sessions() if s.get_profile_name() == profile_name ]
         elif return_session_names:
-            return self.running_sessions() and [ s.session_name for s in self.running_sessions() if s.profile_name == profile_name ]
+            return self.running_sessions() and [ s.session_name for s in self.running_sessions() if s.get_profile_name() == profile_name ]
         else:
-            return self.running_sessions() and [ s.get_uuid() for s in self.running_sessions() if s.profile_name == profile_name ]
+            return self.running_sessions() and [ s.get_uuid() for s in self.running_sessions() if s.get_profile_name() == profile_name ]
 
     def suspended_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
         """\
@@ -920,11 +934,11 @@ class X2goSessionRegistry(object):
 
         """
         if return_objects:
-            return self.suspended_sessions() and [ s for s in self.suspended_sessions() if s.profile_name == profile_name ]
+            return self.suspended_sessions() and [ s for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
         elif return_session_names:
-            return self.suspended_sessions() and [ s.session_name for s in self.suspended_sessions() if s.profile_name == profile_name ]
+            return self.suspended_sessions() and [ s.session_name for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
         else:
-            return self.suspended_sessions() and [ s.get_uuid() for s in self.suspended_sessions() if s.profile_name == profile_name ]
+            return self.suspended_sessions() and [ s.get_uuid() for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
 
     def control_session_of_profile_name(self, profile_name):
         """\
@@ -965,7 +979,7 @@ class X2goSessionRegistry(object):
         else:
             return self.connected_sessions(return_profile_ids=return_profile_ids, return_profile_names=return_profile_names)
 
-    def master_session(self, profile_name, return_object=True, return_session_name=False):
+    def get_master_session(self, profile_name, return_object=True, return_session_name=False):
         """\
         Retrieve the master session of a specific profile.
 
diff --git a/x2go/session.py b/x2go/session.py
index a3fdb8b..c966ac9 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -446,12 +446,17 @@ class X2goSession(object):
         """
         self.logger('Using session %s as master session for profile %s.' % (self.get_session_name(), self.get_profile_name()), loglevel=log.loglevel_NOTICE)
         self.master_session = True
+        if self.has_terminal_session():
+            self.share_all_local_folders()
 
     def unset_master_session(self):
         """\
         Declare this as a non-master session of a connection channel.
 
         """
+        # unmount shared folders
+        if self.has_terminal_session():
+            self.unshare_all_local_folders()
         self.master_session = False
 
     def set_server(self, server):
@@ -1055,10 +1060,8 @@ class X2goSession(object):
         if self.is_alive():
 
             # unmount shared folders
-            try:
-                self.unshare_all_local_folders()
-            except x2go_exceptions.X2goSessionException:
-                pass
+            if self.has_terminal_session():
+                self.unshare_all_local_folders(force_all=True)
 
             self.control_session.clean_sessions(destroy_terminals=destroy_terminals, published_applications=published_applications)
         else:
@@ -1210,6 +1213,18 @@ class X2goSession(object):
             return self.terminal_session.is_published_applications_provider()
         return False
 
+    def is_desktop_session(self):
+        """\
+        Returns true if this session is configured as desktop session.
+
+        @return: Returns C{True} is this session is a desktop session.
+        @rtype: C{bool}
+
+        """
+        if self.has_terminal_session():
+            return self.terminal_session.is_desktop_session()
+        return False
+
     def get_published_applications(self):
         """\
         Return a list of published menu items from the X2Go server
@@ -1284,6 +1299,8 @@ class X2goSession(object):
 
             if self.has_terminal_session() and not self.faulty:
 
+                self.terminal_session.session_info_protect()
+
                 # only run the session startup command if we do not resume...
                 if _new_session:
                     self.terminal_session.run_command(env=self.session_environment)
@@ -1326,15 +1343,7 @@ class X2goSession(object):
                     self.HOOK_mimebox_not_available()
                     self._SUPPORTED_MIMEBOX = False
 
-                try:
-                    if self._SUPPORTED_FOLDERSHARING and self.share_local_folders and self.terminal_session and not self.faulty and self.is_folder_sharing_available():
-                        if _control.get_transport().reverse_tunnels[self.terminal_session.get_session_name()]['sshfs'][1] is not None:
-                            for _folder in self.share_local_folders:
-                                self.share_local_folder(_folder)
-                except x2go_exceptions.X2goUserException, e:
-                    self.logger('%s' % str(e), loglevel=log.loglevel_WARN)
-                    self.HOOK_foldersharing_not_available()
-                    self._SUPPORTED_FOLDERSHARING = False
+                self.share_all_local_folders()
 
                 self.virgin = False
                 self.suspended = False
@@ -1342,6 +1351,7 @@ class X2goSession(object):
                 self.terminated = False
                 self.faulty = False
 
+                self.terminal_session.session_info_unprotect()
                 return True
 
             else:
@@ -1452,10 +1462,7 @@ class X2goSession(object):
             if self.has_terminal_session():
 
                 # unmount shared folders
-                try:
-                    self.unshare_all_local_folders()
-                except x2go_exceptions.X2goSessionException:
-                    pass
+                self.unshare_all_local_folders(force_all=True)
 
                 if self.terminal_session.suspend():
 
@@ -1497,10 +1504,7 @@ class X2goSession(object):
             if self.has_terminal_session():
 
                 # unmount shared folders
-                try:
-                    self.unshare_all_local_folders()
-                except x2go_exceptions.X2goSessionException:
-                    pass
+                self.unshare_all_local_folders(force_all=True)
 
                 if self.terminal_session.terminate():
                     self.running = False
@@ -1710,6 +1714,29 @@ class X2goSession(object):
             raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
     __share_local_folder = share_local_folder
 
+    def share_all_local_folders(self):
+        """\
+        Share all local folders configured to be mounted within this X2Go session.
+
+        @return: returns C{True} if all local folders could be successfully mounted
+            inside this X2Go session
+        @rtype: C{bool}
+
+        """
+        _retval = False
+        if self.has_terminal_session():
+            if self._SUPPORTED_FOLDERSHARING and self.share_local_folders and self.terminal_session and not self.faulty and self.is_folder_sharing_available():
+                if self.control_session.get_transport().reverse_tunnels[self.terminal_session.get_session_name()]['sshfs'][1] is not None:
+                    _retval = True
+                    for _folder in self.share_local_folders:
+                        try:
+                            _retval = self.share_local_folder(_folder) and _retval
+                        except x2go_exceptions.X2goUserException, e:
+                            self.logger('%s' % str(e), loglevel=log.loglevel_WARN)
+            else:
+                self.HOOK_foldersharing_not_available()
+        return _retval
+
     def unshare_all_local_folders(self, force_all=False):
         """\
         Unshare all local folders mounted within this X2Go session.


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