[X2Go-Commits] python-x2go.git - build-baikal (branch) updated: 0.1.1.4-242-g63ac948
X2Go dev team
git-admin at x2go.org
Wed Jan 8 15:31:04 CET 2014
The branch, build-baikal has been updated
via 63ac948ac2d787b9d82dc086d316f7c7b1246cf3 (commit)
from 97c0d9d61117c7924dd368053cab595704efbccb (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 | 6 ++
x2go/backends/control/_stdout.py | 52 ++++-----
x2go/backends/proxy/_nx3.py | 4 +-
x2go/backends/proxy/base.py | 22 ++--
x2go/backends/terminal/_stdout.py | 216 +++++++++++++++++++++----------------
x2go/client.py | 4 +-
x2go/forward.py | 44 ++++----
x2go/registry.py | 4 +-
x2go/session.py | 55 +++++-----
x2go/sftpserver.py | 3 +
x2go/sshproxy.py | 6 ++
x2go/x2go_exceptions.py | 1 +
12 files changed, 234 insertions(+), 183 deletions(-)
The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index bb03bc8..98d3ae5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -128,6 +128,12 @@ python-x2go (0.1.2.0-0~x2go1) UNRELEASED; urgency=low
- Allow custom commands to be desktop sessions.
- X2goSession instances cannot raise X2goClientExceptions.
- Be more tolerant against suspension failures while taking over a session.
+ - Use Paramiko transport compression if available.
+ - Prohibit simultaneous calls to terminal_session.share_local_folders().
+ - Cache SSH transport's getpeername() and get_username().
+ - Catch session startup failures due to faulty port forwarding tunnels
+ and make the notifiable via hooks.
+ - Properly set setkbd value for x2gostartagent and x2goresume-session.
* 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/control/_stdout.py b/x2go/backends/control/_stdout.py
index a5d08ba..74c2350 100644
--- a/x2go/backends/control/_stdout.py
+++ b/x2go/backends/control/_stdout.py
@@ -122,6 +122,8 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
self._session_auth_rsakey = None
self._remote_home = None
self._remote_group = {}
+ self._remote_username = None
+ self._remote_peername = None
self._server_features = None
@@ -306,26 +308,26 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
Returns the control session's remote username.
"""
- if self.get_transport() is not None:
- try:
- return self.get_transport().get_username()
- except:
- raise x2go_exceptions.X2goControlSessionException('Lost connection to X2Go server')
- else:
- return None
+ if self._remote_username is None:
+ if self.get_transport() is not None:
+ try:
+ self._remote_username = self.get_transport().get_username()
+ except:
+ raise x2go_exceptions.X2goControlSessionException('Lost connection to X2Go server')
+ return self._remote_username
def remote_peername(self):
"""\
Returns the control session's remote host (name or ip).
"""
- if self.get_transport() is not None:
- try:
- return self.get_transport().getpeername()
- except:
- raise x2go_exceptions.X2goControlSessionException('Lost connection to X2Go server')
- else:
- return None
+ if self._remote_peername is None:
+ if self.get_transport() is not None:
+ try:
+ self._remote_peername = self.get_transport().getpeername()
+ except:
+ raise x2go_exceptions.X2goControlSessionException('Lost connection to X2Go server')
+ return self._remote_peername
@property
def _x2go_session_auth_rsakey(self):
@@ -476,6 +478,11 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
key_filename=key_filename, timeout=timeout, allow_agent=allow_agent,
look_for_keys=look_for_keys)
+ # since Paramiko 1.7.7.1 there is compression available, let's use it if present...
+ t = self.get_transport()
+ if hasattr(t, 'use_compression'):
+ t.use_compression(compress=True)
+
except paramiko.AuthenticationException, e:
self.close()
if password:
@@ -830,7 +837,7 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
"""
return self.resume(**kwargs)
- def resume(self, session_name=None, session_instance=None, **kwargs):
+ def resume(self, session_name=None, session_instance=None, session_list=None, **kwargs):
"""\
Resume a running/suspended X2Go session.
@@ -845,7 +852,10 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
raise x2go_exceptions.X2goUserException('remote user %s is not allowed to run X2Go commands' % self.get_transport().get_username())
if session_name is not None:
- session_info = self.list_sessions()[session_name]
+ if session_list:
+ session_info = session_list[session_name]
+ else:
+ session_info = self.list_sessions()[session_name]
else:
session_info = None
@@ -862,16 +872,10 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
_success = False
if session_name is not None:
- try:
- _success = _terminal.resume()
- except x2go_exceptions.X2goFwTunnelException:
- pass
+ _success = _terminal.resume()
else:
- try:
- _success = _terminal.start()
- except x2go_exceptions.X2goFwTunnelException:
- pass
+ _success = _terminal.start()
if _success:
while not _terminal.ok():
diff --git a/x2go/backends/proxy/_nx3.py b/x2go/backends/proxy/_nx3.py
index e5ada98..7005178 100644
--- a/x2go/backends/proxy/_nx3.py
+++ b/x2go/backends/proxy/_nx3.py
@@ -164,11 +164,11 @@ options=%s""" % ( self.proxy_options['xkbrules'],
self.logger('NX3 Proxy mode is server, cookie=%s, host=127.0.0.1, port=%s.' % (self.session_info.cookie, self.session_info.graphics_port,), loglevel=log.loglevel_DEBUG)
self.logger('NX3 proxy writes session log to %s.' % os.path.join(self.session_info.local_container, 'session.log'), loglevel=log.loglevel_DEBUG)
- p = base.X2goProxyBASE.start_proxy(self)
+ p, p_ok = base.X2goProxyBASE.start_proxy(self)
if self.ok():
self.logger('NX3 proxy is up and running.', loglevel=log.loglevel_INFO)
else:
self.logger('Bringing up NX3 proxy failed.', loglevel=log.loglevel_ERROR)
- return p
+ return p, self.ok()
diff --git a/x2go/backends/proxy/base.py b/x2go/backends/proxy/base.py
index 0c1586c..028190a 100644
--- a/x2go/backends/proxy/base.py
+++ b/x2go/backends/proxy/base.py
@@ -168,7 +168,7 @@ class X2goProxyBASE(threading.Thread):
return None
try:
- os.mkdir(self.session_info.local_container)
+ os.makedirs(self.session_info.local_container)
except OSError, e:
if e.errno == 17:
# file exists
@@ -273,15 +273,17 @@ class X2goProxyBASE(threading.Thread):
self.logger('waiting for proxy to come up: 0.4s x %s' % _count, loglevel=log.loglevel_DEBUG)
gevent.sleep(.4)
- # also wait for fw_tunnel to become active
- _count = 0
- _maxwait = 40
- while not self.fw_tunnel.is_active and _count < _maxwait:
- _count += 1
- self.logger('waiting for port fw tunnel to come up: 0.5s x %s' % _count, loglevel=log.loglevel_DEBUG)
- gevent.sleep(.5)
+ if self.proxy:
+
+ # also wait for fw_tunnel to become active
+ _count = 0
+ _maxwait = 40
+ while not self.fw_tunnel.is_active and not self.fw_tunnel.failed and _count < _maxwait:
+ _count += 1
+ self.logger('waiting for port fw tunnel to come up: 0.5s x %s' % _count, loglevel=log.loglevel_DEBUG)
+ gevent.sleep(.5)
- return self.proxy
+ return self.proxy, bool(self.proxy) and self.fw_tunnel.is_active
def ok(self):
"""\
@@ -291,4 +293,4 @@ class X2goProxyBASE(threading.Thread):
@rtype C{bool}
"""
- return bool(self.proxy and self.proxy.poll() is None)
+ return bool(self.proxy and self.proxy.poll() is None) and self.fw_tunnel.is_active
diff --git a/x2go/backends/terminal/_stdout.py b/x2go/backends/terminal/_stdout.py
index 4c401a7..7199ad8 100644
--- a/x2go/backends/terminal/_stdout.py
+++ b/x2go/backends/terminal/_stdout.py
@@ -322,6 +322,7 @@ class X2goTerminalSessionSTDOUT(object):
else:
self.client_instance = None
+ self._share_local_folder_busy = False
self._mk_sessions_rootdir(self.params.rootdir)
self.session_info = session_info
@@ -366,7 +367,7 @@ class X2goTerminalSessionSTDOUT(object):
def _mk_sessions_rootdir(self, d):
try:
- os.mkdir(d)
+ os.makedirs(d)
except OSError, e:
if e.errno == 17:
# file exists
@@ -504,6 +505,8 @@ class X2goTerminalSessionSTDOUT(object):
self.reverse_tunnels[self.session_info.name]['sshfs'] = (self.session_info.sshfs_port, _tunnel)
_tunnel.start()
self.active_threads.append(_tunnel)
+ while not _tunnel.ready:
+ gevent.sleep(.1)
else:
# tunnel has already been started and might simply need a resume call
@@ -539,7 +542,7 @@ class X2goTerminalSessionSTDOUT(object):
spool_dir = os.path.join(self.session_info.local_container, 'spool')
if not os.path.exists(spool_dir):
- os.mkdir(spool_dir)
+ os.makedirs(spool_dir)
self.share_local_folder(local_path=spool_dir, folder_type='spool')
self.print_queue = printqueue.X2goPrintQueue(profile_name=self.profile_name,
session_name=self.session_info.name,
@@ -585,7 +588,7 @@ class X2goTerminalSessionSTDOUT(object):
mimebox_dir = os.path.join(self.session_info.local_container, 'mimebox')
if not os.path.exists(mimebox_dir):
- os.mkdir(mimebox_dir)
+ os.makedirs(mimebox_dir)
self.share_local_folder(local_path=mimebox_dir, folder_type='mimebox')
self.mimebox_queue = mimebox.X2goMIMEboxQueue(profile_name=self.profile_name,
session_name=self.session_info.name,
@@ -689,63 +692,75 @@ class X2goTerminalSessionSTDOUT(object):
_x2go_key_fname = '%s/%s/%s' % (os.path.dirname(self.session_info.remote_container), 'ssh', 'key.z%s' % self.session_info.agent_pid)
_x2go_key_bundle = _tmp_io_object.getvalue()
- self.control_session._x2go_sftp_write(_x2go_key_fname, _x2go_key_bundle)
+ # if there is another call to this method currently being processed, wait for that one to finish
+ while self._share_local_folder_busy:
+ gevent.sleep(.1)
+ self._share_local_folder_busy = True
- _convert_encoding = self.params.convert_encoding
- _client_encoding = self.params.client_encoding
- _server_encoding = self.params.server_encoding
+ try:
+ self.control_session._x2go_sftp_write(_x2go_key_fname, _x2go_key_bundle)
- if _X2GOCLIENT_OS == 'Windows':
- local_path = local_path.replace('\\', '/')
- local_path = local_path.replace(':', '')
- local_path = '/windrive/%s' % local_path
- _convert_encoding = True
- _client_encoding = 'WINDOWS-1252'
+ _convert_encoding = self.params.convert_encoding
+ _client_encoding = self.params.client_encoding
+ _server_encoding = self.params.server_encoding
- if _convert_encoding:
- export_iconv_settings = 'export X2GO_ICONV=modules=iconv,from_code=%s,to_code=%s &&' % (_client_encoding, _server_encoding)
- else:
- export_iconv_settings = ''
-
- if folder_type == 'disk':
-
- cmd_line = [ '%s export HOSTNAME &&' % export_iconv_settings,
- 'x2gomountdirs',
- 'dir',
- str(self.session_info.name),
- '"%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),
- ]
-
- elif folder_type == 'spool':
-
- cmd_line = [ '%s export HOSTNAME &&' % export_iconv_settings,
- 'x2gomountdirs',
- 'dir',
- str(self.session_info.name),
- '"%s"' % _CURRENT_LOCAL_USER,
- _x2go_key_fname,
- '%s__PRINT_SPOOL___REVERSESSH_PORT__%s; ' % (local_path, self.session_info.sshfs_port),
- 'rm -f %s %s.ident' % (_x2go_key_fname, _x2go_key_fname),
- ]
-
- elif folder_type == 'mimebox':
-
- cmd_line = [ '%s export HOSTNAME &&' % export_iconv_settings,
- 'x2gomountdirs',
- 'dir',
- str(self.session_info.name),
- '"%s"' % _CURRENT_LOCAL_USER,
- _x2go_key_fname,
- '%s__MIMEBOX_SPOOL___REVERSESSH_PORT__%s; ' % (local_path, self.session_info.sshfs_port),
- 'rm -f %s %s.ident' % (_x2go_key_fname, _x2go_key_fname),
- ]
+ if _X2GOCLIENT_OS == 'Windows':
+ local_path = local_path.replace('\\', '/')
+ local_path = local_path.replace(':', '')
+ local_path = '/windrive/%s' % local_path
+ _convert_encoding = True
+ _client_encoding = 'WINDOWS-1252'
- (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 _convert_encoding:
+ export_iconv_settings = 'export X2GO_ICONV=modules=iconv,from_code=%s,to_code=%s &&' % (_client_encoding, _server_encoding)
+ else:
+ export_iconv_settings = ''
+
+ if folder_type == 'disk':
+
+ cmd_line = [ '%s export HOSTNAME &&' % export_iconv_settings,
+ 'x2gomountdirs',
+ 'dir',
+ str(self.session_info.name),
+ '"%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),
+ ]
+
+ elif folder_type == 'spool':
+
+ cmd_line = [ '%s export HOSTNAME &&' % export_iconv_settings,
+ 'x2gomountdirs',
+ 'dir',
+ str(self.session_info.name),
+ '"%s"' % _CURRENT_LOCAL_USER,
+ _x2go_key_fname,
+ '%s__PRINT_SPOOL___REVERSESSH_PORT__%s; ' % (local_path, self.session_info.sshfs_port),
+ 'rm -f %s %s.ident' % (_x2go_key_fname, _x2go_key_fname),
+ ]
+
+ elif folder_type == 'mimebox':
+
+ cmd_line = [ '%s export HOSTNAME &&' % export_iconv_settings,
+ 'x2gomountdirs',
+ 'dir',
+ str(self.session_info.name),
+ '"%s"' % _CURRENT_LOCAL_USER,
+ _x2go_key_fname,
+ '%s__MIMEBOX_SPOOL___REVERSESSH_PORT__%s; ' % (local_path, self.session_info.sshfs_port),
+ 'rm -f %s %s.ident' % (_x2go_key_fname, _x2go_key_fname),
+ ]
+
+ (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)
+
+ except:
+ raise
+ finally:
+ # allow sharing of other folders again
+ self._share_local_folder_busy = False
if len(_stdout) >= 6 and _stdout[5].endswith('ok'):
return True
@@ -1036,20 +1051,29 @@ class X2goTerminalSessionSTDOUT(object):
return self.session_info.is_published_applications_provider()
return False
- def exec_published_application(self, exec_name, timeout=20):
+ def exec_published_application(self, exec_name, timeout=20, env={}):
"""\
Executed a published application.
@param exec_name: application to be executed
@type exec_name: C{str}
+ @param timeout: execution timeout
+ @type timeout: C{int}
+ @param env: session environment dictionary
+ @type env: C{dict}
+
"""
cmd_line = [
- "export DISPLAY=:%s &&" % str(self.session_info.display),
- "export X2GO_SESSION=%s &&" % str(self.get_session_name()),
+ "export DISPLAY=:%s && " % str(self.session_info.display),
+ "export X2GO_SESSION=%s && " % str(self.get_session_name()),
]
if self.params.snd_system == 'pulse':
- cmd_line.append("export PULSE_CLIENTCONFIG=%s/.pulse-client.conf &&" % self.session_info.remote_container)
+ cmd_line.append("export PULSE_CLIENTCONFIG=%s/.pulse-client.conf && " % self.session_info.remote_container)
+
+ if env:
+ for env_var in env.keys():
+ cmd_line = [ 'export %s=%s && ' % (env_var, env[env_var]) ] + cmd_line
cmd_line.extend(
[
@@ -1057,6 +1081,7 @@ class X2goTerminalSessionSTDOUT(object):
"&> /dev/null & exit",
]
)
+
self.logger('executing published application %s for %s with command line: %s' % (exec_name, self.profile_name, cmd_line), loglevel=log.loglevel_DEBUG)
(stdin, stdout, stderr) = self.control_session._x2go_exec_command(cmd_line, timeout=timeout)
@@ -1121,8 +1146,8 @@ class X2goTerminalSessionSTDOUT(object):
return False
setkbd = "0"
- if self.params.kblayout or self.params.kbtype:
- setkbd = "1"
+ if (self.params.kblayout != "null") or (self.params.kbtype != "null/null"):
+ setkbd = "0"
if '/' in self.params.cmd:
self.params.cmd = os.path.basename(self.params.cmd)
@@ -1182,18 +1207,20 @@ class X2goTerminalSessionSTDOUT(object):
session_instance=self.session_instance,
proxy_options=self.proxy_options,
logger=self.logger)
- self.proxy_subprocess = self.proxy.start_proxy()
- self.active_threads.append(self.proxy)
+ self.proxy_subprocess, proxy_ok = self.proxy.start_proxy()
- if self.params.session_type in ('D', 'S'):
- self.find_session_window()
- self.auto_session_window_title()
- self.raise_session_window()
+ if proxy_ok:
+ self.active_threads.append(self.proxy)
- if self.params.published_applications:
- self.control_session.get_published_applications()
+ if self.params.session_type in ('D', 'S'):
+ self.find_session_window()
+ self.auto_session_window_title()
+ self.raise_session_window()
- return self.ok()
+ if self.params.published_applications:
+ self.control_session.get_published_applications()
+
+ return proxy_ok
def resume(self):
"""\
@@ -1207,7 +1234,7 @@ class X2goTerminalSessionSTDOUT(object):
"""
setkbd = "0"
- if self.params.kblayout or self.params.kbtype:
+ if (self.params.kblayout != "null") or (self.params.kbtype != "null/null"):
setkbd = "1"
cmd_line = [ "x2goresume-session", self.session_info.name,
@@ -1253,28 +1280,29 @@ class X2goTerminalSessionSTDOUT(object):
session_instance=self.session_instance,
logger=self.logger
)
- self.proxy_subprocess = self.proxy.start_proxy()
-
- # local path may be a Windows path, so we use the path separator of the local system
- self.session_info.local_container = os.path.join(self.params.rootdir, 'S-%s' % self.session_info.name)
- # remote path is always a UniX path...
- self.session_info.remote_container = '%s/.x2go/C-%s' % (self.control_session._x2go_remote_home,
- self.session_info.name,
- )
- self.params.depth = self.session_info.name.split('_')[2][2:]
- # on a session resume the user name comes in as a user ID. We have to translate this...
- self.session_info.username = self.control_session.remote_username()
-
- if self.params.session_type in ('D', 'S'):
- self.find_session_window()
- self.auto_session_window_title()
- self.raise_session_window()
-
- if self.is_published_applications_provider():
- self.control_session.get_published_applications()
- self.published_applications = True
-
- return self.ok()
+ self.proxy_subprocess, proxy_ok = self.proxy.start_proxy()
+
+ if proxy_ok:
+ # local path may be a Windows path, so we use the path separator of the local system
+ self.session_info.local_container = os.path.join(self.params.rootdir, 'S-%s' % self.session_info.name)
+ # remote path is always a UniX path...
+ self.session_info.remote_container = '%s/.x2go/C-%s' % (self.control_session._x2go_remote_home,
+ self.session_info.name,
+ )
+ self.params.depth = self.session_info.name.split('_')[2][2:]
+ # on a session resume the user name comes in as a user ID. We have to translate this...
+ self.session_info.username = self.control_session.remote_username()
+
+ if self.params.session_type in ('D', 'S'):
+ self.find_session_window()
+ self.auto_session_window_title()
+ self.raise_session_window()
+
+ if self.is_published_applications_provider():
+ self.control_session.get_published_applications()
+ self.published_applications = True
+
+ return proxy_ok
def suspend(self):
"""\
diff --git a/x2go/client.py b/x2go/client.py
index 7e81e4b..5bbdb17 100644
--- a/x2go/client.py
+++ b/x2go/client.py
@@ -1480,9 +1480,9 @@ class X2goClient(object):
raise x2go_exceptions.X2goClientException('don\'t know which session to resume')
if session_uuid is None:
session_uuid = self.session_registry.get_session_of_session_name(session_name=session_name, return_object=False)
- return self.session_registry(session_uuid).resume()
+ return self.session_registry(session_uuid).resume(session_list=self.list_sessions(session_uuid=session_uuid))
else:
- return self.session_registry(session_uuid).resume(session_name=session_name)
+ return self.session_registry(session_uuid).resume(session_name=session_name, session_list=self.list_sessions(session_uuid=session_uuid))
except x2go_exceptions.X2goControlSessionException:
profile_name = self.get_session_profile_name(session_uuid)
self.HOOK_on_control_session_death(profile_name)
diff --git a/x2go/forward.py b/x2go/forward.py
index dca0e70..b10e86f 100644
--- a/x2go/forward.py
+++ b/x2go/forward.py
@@ -72,6 +72,7 @@ class X2goFwServer(StreamServer):
self.chan = None
self.is_active = False
+ self.failed = False
self.keepalive = False
self.chain_host = remote_host
self.chain_port = remote_port
@@ -124,26 +125,24 @@ class X2goFwServer(StreamServer):
loglevel=log.loglevel_WARN)
gevent.sleep(.4)
-
if not _success:
self.logger('incoming request to %s:%d failed after %d attempts' % (self.chain_host,
self.chain_port,
_count),
loglevel=log.loglevel_ERROR)
+ if self.session_instance:
+ self.session_instance.HOOK_forwarding_tunnel_setup_failed(chain_host=self.chain_host, chain_port=self.chain_port)
+ self.failed = True
+
else:
+
+ self.logger('connected! Tunnel open %r -> %r -> %r' % (self.fw_socket.getpeername(),
+ chan_peername, (self.chain_host, self.chain_port)),
+ loglevel=log.loglevel_INFO)
+
# once we are here, we can presume the tunnel to be active...
self.is_active = True
- if self.chan is None:
- self.logger('incoming request to [%s]:%d was rejected by the SSH server.' %
- (self.chain_host, self.chain_port), loglevel=log.loglevel_ERROR)
- if self.session_instance:
- self.session_instance.HOOK_forwarding_tunnel_setup_failed(chain_host=self.chain_host, chain_port=self.chain_port)
- return
- else:
- self.logger('connected! Tunnel open %r -> %r -> %r' % (self.fw_socket.getpeername(),
- chan_peername, (self.chain_host, self.chain_port)),
- loglevel=log.loglevel_INFO)
self.keepalive = True
try:
while self.keepalive:
@@ -243,22 +242,19 @@ def start_forward_tunnel(local_host='127.0.0.1', local_port=22022,
@rtype: C{instance}
"""
+ fw_server = X2goFwServer(listener=(local_host, local_port),
+ remote_host=remote_host, remote_port=remote_port,
+ ssh_transport=ssh_transport, session_instance=session_instance,
+ logger=logger,
+ )
try:
- fw_server = X2goFwServer(listener=(local_host, local_port),
- remote_host=remote_host, remote_port=remote_port,
- ssh_transport=ssh_transport, session_instance=session_instance,
- logger=logger,
- )
- try:
- fw_server.start()
- return fw_server
- except socket.error:
- pass
- except x2go_exceptions.X2goFwTunnelException:
+ fw_server.start()
+ except socket.error:
+ fw_server.failed = True
+ fw_server.is_active = False
pass
- return None
-
+ return fw_server
def stop_forward_tunnel(fw_server):
"""\
diff --git a/x2go/registry.py b/x2go/registry.py
index 54b9a16..0b25e4d 100644
--- a/x2go/registry.py
+++ b/x2go/registry.py
@@ -312,8 +312,8 @@ class X2goSessionRegistry(object):
# 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):
+ self(_session_uuid).unset_master_session()
del self.master_sessions[_profile_name]
# session has been suspended
@@ -324,8 +324,8 @@ class X2goSessionRegistry(object):
# 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):
+ self(_session_uuid).unset_master_session()
del self.master_sessions[_profile_name]
# session has terminated
diff --git a/x2go/session.py b/x2go/session.py
index 22f8ac9..35db50a 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -488,7 +488,7 @@ 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
- self.share_all_local_folders()
+ gevent.spawn(self.share_all_local_folders)
def unset_master_session(self):
"""\
@@ -866,7 +866,6 @@ class X2goSession(object):
@return: returns C{True} if this L{X2goSession} has a terminal session associated to itself
@rtype: C{bool}
-
"""
return self.terminal_session not in (None, 'PENDING')
__has_terminal_session = has_terminal_session
@@ -1374,7 +1373,7 @@ class X2goSession(object):
"""
if self.terminal_session is not None:
self.logger('for %s executing published application: %s' % (self.profile_name, exec_name), loglevel=log.loglevel_NOTICE)
- self.terminal_session.exec_published_application(exec_name, timeout=timeout)
+ self.terminal_session.exec_published_application(exec_name, timeout=timeout, env=self.session_environment)
__exec_published_application = exec_published_application
def do_auto_start_or_resume(self, newest=True, oldest=False, all_suspended=False, start=True, redirect_to_client=True):
@@ -1423,7 +1422,7 @@ class X2goSession(object):
if not self.published_applications:
return self.start()
- def resume(self, session_name=None):
+ def resume(self, session_name=None, session_list=None):
"""\
Resume or continue a suspended / running X2Go session on the
remote X2Go server.
@@ -1441,11 +1440,13 @@ class X2goSession(object):
self.session_name = session_name
if self.is_alive():
+
_control = self.control_session
# FIXME: normally this part gets called if you suspend a session that is associated to another client
# we do not have a possibility to really check if SSH has released port forwarding channels or
# sockets, thus we plainly have to wait a while
+
if self.is_running():
try:
self.suspend()
@@ -1462,6 +1463,7 @@ class X2goSession(object):
self.terminal_session = _control.resume(session_name=self.session_name,
session_instance=self,
+ session_list=session_list,
logger=self.logger, **self.terminal_params)
if self.session_name is None:
@@ -1476,10 +1478,6 @@ class X2goSession(object):
self.terminal_session.session_info_protect()
- # only run the session startup command if we do not resume...
- if _new_session:
- self.has_terminal_session() and self.terminal_session.run_command(env=self.session_environment)
-
if self.get_session_cmd() != 'PUBLISHED':
self.published_applications = False
@@ -1500,24 +1498,27 @@ class X2goSession(object):
self._SUPPORTED_MIMEBOX = False
self._SUPPORTED_FOLDERSHARING = False
- try:
- if self._SUPPORTED_PRINTING and self.printing:
- self.has_terminal_session() and not self.faulty and self.terminal_session.start_printing()
+ if self._SUPPORTED_PRINTING and self.printing:
+ try:
+ self.has_terminal_session() and not self.faulty and gevent.spawn(self.terminal_session.start_printing)
self.has_terminal_session() and not self.faulty and self.session_environment.update({'X2GO_SPOOLDIR': self.terminal_session.get_printing_spooldir(), })
- except x2go_exceptions.X2goUserException, e:
- self.logger('%s' % str(e), loglevel=log.loglevel_WARN)
- self.HOOK_printing_not_available()
- self._SUPPORTED_PRINTING = False
-
- try:
- if self._SUPPORTED_MIMEBOX and self.allow_mimebox:
- self.has_terminal_session() and not self.faulty and self.terminal_session.start_mimebox(mimebox_extensions=self.mimebox_extensions, mimebox_action=self.mimebox_action)
+ except x2go_exceptions.X2goUserException, e:
+ self.logger('%s' % str(e), loglevel=log.loglevel_WARN)
+ self.HOOK_printing_not_available()
+ self._SUPPORTED_PRINTING = False
+
+ if self._SUPPORTED_MIMEBOX and self.allow_mimebox:
+ try:
+ self.has_terminal_session() and not self.faulty and gevent.spawn(self.terminal_session.start_mimebox, mimebox_extensions=self.mimebox_extensions, mimebox_action=self.mimebox_action)
self.has_terminal_session() and self.session_environment.update({'X2GO_MIMEBOX': self.terminal_session.get_mimebox_spooldir(), })
- except x2go_exceptions.X2goUserException, e:
- self.logger('%s' % str(e), loglevel=log.loglevel_WARN)
- self.HOOK_mimebox_not_available()
- self._SUPPORTED_MIMEBOX = False
+ except x2go_exceptions.X2goUserException, e:
+ self.logger('%s' % str(e), loglevel=log.loglevel_WARN)
+ self.HOOK_mimebox_not_available()
+ self._SUPPORTED_MIMEBOX = False
+ # only run the session startup command if we do not resume...
+ if _new_session:
+ self.has_terminal_session() and self.terminal_session.run_command(env=self.session_environment)
self.virgin = False
self.suspended = False
@@ -1525,7 +1526,11 @@ class X2goSession(object):
self.terminated = False
self.faulty = False
- self.share_all_local_folders()
+ # if there is a client instance for X2Go sessions that the client instance will handle the mounting of shared folders
+ if (not self.client_instance) and \
+ self._SUPPORTED_FOLDERSHARING and \
+ self.allow_share_local_folders:
+ gevent.spawn(self.share_all_local_folders)
self.has_terminal_session() and self.terminal_session.session_info_unprotect()
return True
@@ -1916,7 +1921,7 @@ class X2goSession(object):
"""
_retval = False
if self.has_terminal_session() and self.share_local_folders and not self.faulty and self.is_running() and self.allow_share_local_folders:
- if self._SUPPORTED_FOLDERSHARING and self.is_folder_sharing_available():
+ if self.is_folder_sharing_available() and self.is_master_session():
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:
diff --git a/x2go/sftpserver.py b/x2go/sftpserver.py
index 678f838..08243f7 100644
--- a/x2go/sftpserver.py
+++ b/x2go/sftpserver.py
@@ -493,6 +493,7 @@ class X2goRevFwTunnelToSFTP(rforward.X2goRevFwTunnel):
@type loglevel: int
"""
+ self.ready = False
if logger is None:
self.logger = log.X2goLogger(loglevel=loglevel)
else:
@@ -535,6 +536,7 @@ class X2goRevFwTunnelToSFTP(rforward.X2goRevFwTunnel):
"""
self._request_port_forwarding()
self._keepalive = True
+ self.ready = True
while self._keepalive:
self.incoming_channel.acquire()
@@ -560,6 +562,7 @@ class X2goRevFwTunnelToSFTP(rforward.X2goRevFwTunnel):
)
_new_chan_thread.start()
self.open_channels['[%s]:%s' % _chan.origin_addr] = _new_chan_thread
+ self.ready = False
def x2go_rev_forward_sftpchannel_handler(chan=None, auth_key=None, logger=None):
diff --git a/x2go/sshproxy.py b/x2go/sshproxy.py
index 53dc8b9..7f28234 100644
--- a/x2go/sshproxy.py
+++ b/x2go/sshproxy.py
@@ -200,6 +200,7 @@ class X2goSSHProxy(paramiko.SSHClient, threading.Thread):
look_for_keys=False,
allow_agent=False,
)
+
except x2go_exceptions.AuthenticationException, e:
self.close()
raise x2go_exceptions.X2goSSHProxyAuthenticationException('pubkey auth mechanisms both failed')
@@ -207,6 +208,11 @@ class X2goSSHProxy(paramiko.SSHClient, threading.Thread):
self.close()
raise
+ # since Paramiko 1.7.7.1 there is compression available, let's use it if present...
+ t = self.get_transport()
+ if hasattr(t, 'use_compression'):
+ t.use_compression(compress=True)
+
# if there is not private key, we will use the given password, if any
else:
# create a random password if password is empty to trigger host key validity check
diff --git a/x2go/x2go_exceptions.py b/x2go/x2go_exceptions.py
index 1525359..a8eaa3f 100644
--- a/x2go/x2go_exceptions.py
+++ b/x2go/x2go_exceptions.py
@@ -58,6 +58,7 @@ class X2goRevFwTunnelException(_X2goException): pass
class X2goPrintException(_X2goException): pass
class X2goPrintQueueException(_X2goException): pass
class X2goPrintActionException(_X2goException): pass
+class X2goProxyException(_X2goException): pass
class X2goMIMEboxActionException(_X2goException): pass
class X2goMIMEboxQueueException(_X2goException): pass
class X2goSSHProxyException(_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