[X2Go-Commits] python-x2go.git - build-baikal (branch) updated: 0.1.1.4-102-g2f1c22d
X2Go dev team
git-admin at x2go.org
Wed Jan 8 15:26:48 CET 2014
The branch, build-baikal has been updated
via 2f1c22df05d628d18458ded68c27100e8c76dbbc (commit)
from 20934399dd3170bdbbb616eb3d634acd00b647d3 (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 | 2 +
x2go/backends/terminal/_stdout.py | 2 +-
x2go/cache.py | 10 +++--
x2go/client.py | 52 ++++++++++++++++---------
x2go/registry.py | 77 ++++++++++++++++++++++++++++++++++---
x2go/session.py | 57 ++++++++++++++++++++++-----
6 files changed, 161 insertions(+), 39 deletions(-)
The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index 11d28ee..1f876f8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -17,6 +17,8 @@ python-x2go (0.1.2.0-0~x2go1) UNRELEASED; urgency=low
x2goserver >= 3.1.0.0).
- Provide client-side cache of shared local folders, detect server-side
unsharing of client-side folders.
+ - Introduce concept of master sessions per profile to X2goClient class. Only
+ the master session can mount/unmount client-side shared folders.
* Depend on python-xlib.
-- Mike Gabriel <mike.gabriel at das-netzwerkteam.de> Sat, 28 Sep 2012 01:44:21 +0100
diff --git a/x2go/backends/terminal/_stdout.py b/x2go/backends/terminal/_stdout.py
index 4ded9bc..d1db106 100644
--- a/x2go/backends/terminal/_stdout.py
+++ b/x2go/backends/terminal/_stdout.py
@@ -663,7 +663,7 @@ class X2goTerminalSessionSTDOUT(object):
'"%s"' % _CURRENT_LOCAL_USER,
_x2go_key_fname,
'%s__REVERSESSH_PORT__%s; ' % (local_path, self.session_info.sshfs_port),
- 'rm -f %s %s.ident' % (_x2go_key_fname, _x2go_key_fname),
+ 'rm -f %s %s.ident' % (_x2go_key_fname, _x2go_key_fname),
]
elif folder_type == 'spool':
diff --git a/x2go/cache.py b/x2go/cache.py
index a1d6c51..87d2bac 100644
--- a/x2go/cache.py
+++ b/x2go/cache.py
@@ -142,7 +142,6 @@ class X2goListSessionsCache(object):
@type profile_name: C{str}
"""
-
try:
if self.x2go_listsessions_cache[profile_name]['sessions']:
for session_name in self.x2go_listsessions_cache[profile_name]['sessions']:
@@ -251,11 +250,14 @@ class X2goListSessionsCache(object):
@type session_uuid: C{str}
"""
- if profile_name is None and session_uuid:
- profile_name = self.client_instance.get_session_profile_name(session_uuid)
+ if profile_name is None and session_uuid and self.client_instance:
+ try:
+ profile_name = self.client_instance.get_session_profile_name(session_uuid)
+ except x2go_exceptions.X2goSessionRegistryException:
+ raise x2go_exceptions.X2goSessionCacheException("requested session UUID is not valid anymore")
_is_profile_cached = self.x2go_listsessions_cache.has_key(profile_name)
_is_cache_type_cached = _is_profile_cached and self.x2go_listsessions_cache[profile_name].has_key(cache_type)
if cache_type is None:
return _is_profile_cached
else:
- return _is_cache_type_cached
\ No newline at end of file
+ return _is_cache_type_cached
diff --git a/x2go/client.py b/x2go/client.py
index 095598c..880c79d 100644
--- a/x2go/client.py
+++ b/x2go/client.py
@@ -1546,13 +1546,14 @@ class X2goClient(object):
"""
if session_uuid is None and profile_name:
- _connected = self._X2goClient__client_connected_sessions_of_profile_name(profile_name, return_objects=False)
- if len(_connected) > 0:
- session_uuid = _connected[0]
+ session_uuid = self._X2goClient__get_master_session(profile_name, return_object=False)
if session_uuid:
- return self.session_registry(session_uuid).is_folder_sharing_available()
+ try:
+ return self.session_registry(session_uuid).is_folder_sharing_available()
+ except x2go_exceptions.X2goSessionRegistryException:
+ return False
else:
- self.logger('Cannot find a terminal session for profile ,,%s\'\' that can be used to query folder sharing capabilities' % profile_name, loglevel=log.loglevel_WARN)
+ self.logger('Cannot find a terminal session for profile ,,%s\'\' that can be used to query folder sharing capabilities' % profile_name, loglevel=log.loglevel_INFO)
return False
__is_folder_sharing_available = is_folder_sharing_available
__profile_is_folder_sharing_available = is_folder_sharing_available
@@ -1584,11 +1585,12 @@ class X2goClient(object):
if folder_name: local_path = folder_name
if session_uuid is None and profile_name:
- _associated = self._X2goClient__client_associated_sessions_of_profile_name(profile_name, return_objects=False)
- if len(_associated) > 0:
- session_uuid = _associated[0]
+ session_uuid = self._X2goClient__get_master_session(profile_name, return_object=False)
if session_uuid:
- return self.session_registry(session_uuid).share_local_folder(local_path=local_path)
+ try:
+ return self.session_registry(session_uuid).share_local_folder(local_path=local_path)
+ except x2go_exceptions.X2goSessionException:
+ return False
else:
self.logger('Cannot find a terminal session for profile ,,%s\'\' to share a local folder with' % profile_name, loglevel=log.loglevel_WARN)
return False
@@ -1616,9 +1618,7 @@ class X2goClient(object):
"""
if session_uuid is None and profile_name:
- _associated = self._X2goClient__client_associated_sessions_of_profile_name(profile_name, return_objects=False)
- if len(_associated) > 0:
- session_uuid = _associated[0]
+ session_uuid = self._X2goClient__get_master_session(profile_name, return_object=False)
if session_uuid:
return self.session_registry(session_uuid).unshare_all_local_folders()
else:
@@ -1653,9 +1653,7 @@ class X2goClient(object):
"""
if session_uuid is None and profile_name:
- _associated = self._X2goClient__client_associated_sessions_of_profile_name(profile_name, return_objects=False)
- if len(_associated) > 0:
- session_uuid = _associated[0]
+ session_uuid = self._X2goClient__get_master_session(profile_name, return_object=False)
if session_uuid:
return self.session_registry(session_uuid).unshare_local_folder(local_path=local_path)
else:
@@ -1676,9 +1674,7 @@ class X2goClient(object):
"""
if session_uuid is None and profile_name:
- _associated = self._X2goClient__client_associated_sessions_of_profile_name(profile_name, return_objects=False)
- if len(_associated) > 0:
- session_uuid = _associated[0]
+ session_uuid = self._X2goClient__get_master_session(profile_name, return_object=False)
if session_uuid and profile_name is None:
profile_name = self.session_registry(session_uuid).get_profile_name()
@@ -1699,6 +1695,26 @@ class X2goClient(object):
__session_get_shared_folders = get_shared_folders
__profile_get_shared_folders = get_shared_folders
+ def get_master_session(self, profile_name, return_object=True, return_session_name=False):
+ """\
+ Retrieve the master session of a specific profile.
+
+ @param profile_name: the profile name that we query the master session of
+ @type profile_name: C{str}
+ @param return_object: return L{X2goSession} instance
+ @type return_object: C{bool}
+ @param return_session_name: return X2Go session name
+ @type return_session_name: C{bool}
+
+ @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
+ @rtype: C{list}
+
+ """
+ return self.session_registry.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
+
###
### Provide access to the X2goClient's session registry
###
diff --git a/x2go/registry.py b/x2go/registry.py
index 35426f1..1771ae6 100644
--- a/x2go/registry.py
+++ b/x2go/registry.py
@@ -78,6 +78,7 @@ class X2goSessionRegistry(object):
self.registry = {}
self.control_sessions = {}
+ self.master_sessions = {}
self._last_available_session_registration = None
self._skip_auto_registration = False
@@ -263,6 +264,8 @@ class X2goSessionRegistry(object):
_profile_name = self(_session_uuid).get_profile_name()
_session_name = self(_session_uuid).get_session_name()
+ print _session_uuid, _session_name
+
if self(_session_uuid).get_server_hostname() != _current_status['server']:
# if the server (hostname) has changed due to a configuration change we skip all notifications
@@ -279,12 +282,19 @@ class X2goSessionRegistry(object):
else:
# explicitly ask for the terminal_session object directly here, so we also get 'PENDING' terminal sessions here...
if self(_session_uuid).terminal_session:
+
+ # declare as master session if appropriate
+ if _profile_name not in self.master_sessions.keys():
+ self.master_sessions[_profile_name] = self(_session_uuid)
+ self(_session_uuid).set_master_session()
+
if _last_status['suspended']:
# from a suspended state
self.client_instance.HOOK_on_session_has_resumed_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
elif _last_status['virgin']:
# as a new session
self.client_instance.HOOK_on_session_has_started_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
+
else:
if _last_status['suspended']:
# from a suspended state
@@ -293,11 +303,26 @@ class X2goSessionRegistry(object):
# as a new session
self.client_instance.HOOK_on_session_has_started_by_other(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
- elif _last_status['connected'] and (not _last_status['suspended'] and _current_status['suspended']) and not _current_status['faulty']:
+ elif _last_status['connected'] and (not _last_status['suspended'] and _current_status['suspended']) and not _current_status['faulty'] and _session_name:
+
+ # unregister as master session
+ if _profile_name in self.master_sessions.keys():
+ self(_session_uuid).unset_master_session()
+ if self.master_sessions[_profile_name] == self(_session_uuid):
+ del self.master_sessions[_profile_name]
+
# session has been suspended
self(_session_uuid).session_cleanup()
self.client_instance.HOOK_on_session_has_been_suspended(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
- elif _last_status['connected'] and (not _last_status['terminated'] and _current_status['terminated']) and not _current_status['faulty']:
+
+ elif _last_status['connected'] and (not _last_status['terminated'] and _current_status['terminated']) and not _current_status['faulty'] and _session_name:
+
+ # unregister as master session
+ if _profile_name in self.master_sessions.keys():
+ self(_session_uuid).unset_master_session()
+ if self.master_sessions[_profile_name] == self(_session_uuid):
+ del self.master_sessions[_profile_name]
+
# session has terminated
self.client_instance.HOOK_on_session_has_terminated(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
try: self(_session_uuid).session_cleanup()
@@ -307,6 +332,12 @@ class X2goSessionRegistry(object):
if len(self.virgin_sessions_of_profile_name(profile_name)) > 1:
self.forget(_session_uuid)
+ for _profile_name in self.connected_profiles(return_profile_names=True):
+ _running_sessions = self.running_sessions_of_profile_name(_profile_name)
+ if _profile_name not in self.master_sessions.keys() and _running_sessions:
+ self.master_sessions[_profile_name] = _running_sessions[0]
+ _running_sessions[0].set_master_session()
+
return True
def register_available_server_sessions(self, profile_name, session_list=None, newly_connected=False):
@@ -443,7 +474,7 @@ class X2goSessionRegistry(object):
control_session = self.control_sessions[profile_id]
# when starting a new session, we will try to use unused registered virgin sessions
- # depending on your application layout, there shoul either be one or no such virgin session at all
+ # depending on your application layout, there should either be one or no such virgin session at all
_virgin_sessions = self.virgin_sessions_of_profile_name(profile_name, return_objects=True)
if _virgin_sessions and not session_name:
@@ -496,6 +527,9 @@ class X2goSessionRegistry(object):
if profile_id not in self.control_sessions.keys():
self.control_sessions[profile_id] = s.get_control_session()
+ # make sure a new session is a non-master session unless promoted in update_status method
+ self(session_uuid).unset_master_session()
+
return session_uuid
def has_session_of_session_name(self, session_name):
@@ -618,7 +652,6 @@ class X2goSessionRegistry(object):
@return: a session list (as UUID hashes, objects, profile names/IDs or session names)
@rtype: C{list}
-
"""
return self._sessionsWithState('virgin', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
@@ -891,7 +924,7 @@ class X2goSessionRegistry(object):
"""
return [ c for c in self.control_sessions.values() if c.is_connected() ]
- def connected_profiles(self, use_paramiko=False):
+ def connected_profiles(self, use_paramiko=False, return_profile_ids=True, return_profile_names=False):
"""\
Retrieve a list of all currently connected session profiles.
@@ -904,5 +937,37 @@ class X2goSessionRegistry(object):
if use_paramiko:
return [ p for p in self.control_sessions.keys() if self.control_sessions[p].is_connected() ]
else:
- return self.connected_sessions(return_profile_ids=True)
+ 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):
+ """\
+ Retrieve the master session of a specific profile.
+ @param profile_name: the profile name that we query the master session of
+ @type profile_name: C{str}
+ @param return_object: return L{X2goSession} instance
+ @type return_object: C{bool}
+ @param return_session_name: return X2Go session name
+ @type return_session_name: C{bool}
+
+ @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
+ @rtype: C{list}
+
+ """
+ if profile_name not in self.connected_profiles(return_profile_names=True):
+ return None
+
+ if profile_name not in self.master_sessions.keys() or self.master_sessions[profile_name] is None:
+ return None
+
+ _session = self.master_sessions[profile_name]
+
+ if not _session.is_master_session():
+ self.master_sessions[profile_name] = None
+
+ if return_object:
+ return _session
+ elif return_session_name:
+ return _session.get_session_name()
+ else:
+ return _session.get_uuid()
diff --git a/x2go/session.py b/x2go/session.py
index 8167dd8..6c82eaa 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -276,6 +276,7 @@ class X2goSession(object):
self._SUPPORTED_MIMEBOX = SUPPORTED_MIMEBOX
self._SUPPORTED_FOLDERSHARING = SUPPORTED_FOLDERSHARING
+ self.master_session = None
self.init_control_session()
self.terminal_session = None
@@ -364,6 +365,42 @@ class X2goSession(object):
ssh_rootdir=self.ssh_rootdir,
logger=self.logger)
+ def is_master_session(self):
+ """\
+ Is this session a/the master session of sessions.
+
+ The master session is the session has been launched first for a specific connection,
+ it also is _the_ session that controls the client-side shared folders.
+
+ @param server: new server name
+ @type server: C{str}
+
+ """
+ if self.master_session is None:
+ return True
+ return self.master_session
+
+ def set_master_session(self):
+ """\
+ Declare this as a master session of a connection channel.
+
+ @param server: new server name
+ @type server: C{str}
+
+ """
+ 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
+
+ def unset_master_session(self):
+ """\
+ Declare this as a non-master session of a connection channel.
+
+ @param server: new server name
+ @type server: C{str}
+
+ """
+ self.master_session = False
+
def set_server(self, server):
"""\
Modify server name after L{X2goSession} has already been initialized.
@@ -432,6 +469,8 @@ 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
@@ -855,6 +894,7 @@ class X2goSession(object):
self.suspended = None
self.terminated = None
self.faults = None
+ self.master_session = None
try:
self.update_status(force_update=True)
except x2go_exceptions.X2goControlSessionException:
@@ -1493,8 +1533,11 @@ class X2goSession(object):
if self._SUPPORTED_FOLDERSHARING and self.allow_share_local_folders:
if self.is_connected():
return self.control_session.is_folder_sharing_available()
+ else:
+ self.logger('session is not connected, cannot share local folders now', loglevel=log.loglevel_WARN)
else:
self.logger('local folder sharing is disabled for this session profile', loglevel=log.loglevel_WARN)
+ return False
def share_local_folder(self, local_path=None, folder_name=None):
"""\
@@ -1515,13 +1558,11 @@ class X2goSession(object):
if folder_name: local_path=folder_name
if self.has_terminal_session():
- if self._SUPPORTED_FOLDERSHARING and self.allow_share_local_folders:
+ if self.is_folder_sharing_available() and self.is_master_session():
if self.terminal_session.share_local_folder(local_path=local_path):
self.shared_folders.append(local_path)
return True
return False
- else:
- self.logger('local folder sharing is disabled for this session profile', loglevel=log.loglevel_WARN)
else:
raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
__share_local_folder = share_local_folder
@@ -1540,7 +1581,7 @@ class X2goSession(object):
"""
if self.has_terminal_session():
- if self._SUPPORTED_FOLDERSHARING and self.allow_share_local_folders:
+ if self.is_folder_sharing_available() and self.is_master_session():
if force_all:
self.shared_folders = []
return self.terminal_session.unshare_all_local_folders()
@@ -1550,8 +1591,6 @@ class X2goSession(object):
retval = retval | self.terminal_session.unshare_local_folder(_shared_folder)
self.shared_folders = []
return retval
- else:
- self.logger('local folder sharing is disabled for this session profile', loglevel=log.loglevel_WARN)
else:
raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
return False
@@ -1571,11 +1610,9 @@ class X2goSession(object):
"""
if self.has_terminal_session():
- if self._SUPPORTED_FOLDERSHARING and self.allow_share_local_folders and local_path in self.shared_folders:
+ if self.is_folder_sharing_available() and self.is_master_session() and local_path in self.shared_folders:
self.shared_folders.remove(local_path)
return self.terminal_session.unshare_local_folder(local_path=local_path)
- else:
- self.logger('local folder sharing is disabled for this session profile', loglevel=log.loglevel_WARN)
else:
raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
__unshare_local_folder = unshare_local_folder
@@ -1594,7 +1631,7 @@ class X2goSession(object):
@rtype: C{list}
"""
- if self.shared_folders and check_list_mounts:
+ if self.is_folder_sharing_available and self.is_master_session() and self.shared_folders and check_list_mounts:
unshared_folders = []
if mounts is None:
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