This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit 4a261d742746f973b46d0ffe0afa856916ddbdeb Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Dec 10 09:54:36 2014 +0100 More load-balancing improvements... - When load-balancing, switch to chosen server as remote broker agent before deploying SSH keys. - Allow resuming sessions from servers even if one offline server has left bogus in the session DB (plus unit tests). --- debian/changelog | 4 ++ x2gobroker/agent.py | 1 - x2gobroker/brokers/base_broker.py | 25 +++++++---- x2gobroker/tests/test_broker_agent.py | 77 ++++++++++++++++++++++++++++++--- 4 files changed, 92 insertions(+), 15 deletions(-) diff --git a/debian/changelog b/debian/changelog index 94f5c22..d040e38 100644 --- a/debian/changelog +++ b/debian/changelog @@ -211,6 +211,10 @@ x2gobroker (0.0.3.0-0x2go1) UNRELEASED; urgency=low can be switched off via "default-portscan-x2goservers" in x2gobroker.conf or via "broker-portscan-x2goservers" per session profile. (Fixes: #692). + - When load-balancing, switch to chosen server as remote broker agent before + deploying SSH keys. + - Allow resuming sessions from servers even if one offline server has + left bogus in the session DB (plus unit tests). * debian/control: + Provide separate bin:package for SSH brokerage: x2gobroker-ssh. + Replace LDAP support with session brokerage support in LONG_DESCRIPTION. diff --git a/x2gobroker/agent.py b/x2gobroker/agent.py index 94c8d1d..8f7ae9e 100644 --- a/x2gobroker/agent.py +++ b/x2gobroker/agent.py @@ -220,7 +220,6 @@ def _call_remote_broker_agent(username, task, cmdline_args=[], remote_agent=None raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Could not ping remote X2Go Broker Agent host ({remote_hostname})'.format(remote_hostname=remote_hostname)) - def ping(remote_agent=None, **kwargs): """\ Ping X2Go Broker Agent. diff --git a/x2gobroker/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py index afb8ce2..4a6cb00 100644 --- a/x2gobroker/brokers/base_broker.py +++ b/x2gobroker/brokers/base_broker.py @@ -1026,7 +1026,7 @@ class X2GoBroker(object): server_list = server_list[0:-1] - if remote_agent is None: + if not remote_agent: logger_broker.warning('base_broker.X2GoBroker.get_remote_agent(): failed to allocate any broker agent (query-mode: {query_mode}, remote_agent: {remote_agent})'.format(query_mode=agent_query_mode, remote_agent=remote_agent)) elif agent_query_mode == u'LOCAL': @@ -1361,8 +1361,8 @@ class X2GoBroker(object): if server_list: if not self.get_portscan_x2goservers(profile_id) or x2gobroker.utils.portscan(addr=server_name, port=server_port) or x2gobroker.utils.portscan(addr=server_addr, port=server_port): selected_session = { - 'server': server_addr, - 'port': server_port, + u'server': server_addr, + u'port': server_port, } else: server_list.remove(server_name) @@ -1378,15 +1378,15 @@ class X2GoBroker(object): # carries a zombie session entry (that will disappear when the down X2Go Server comes up again (cleanup # via x2gocleansessions). # - # We have to presume that any running/suspended session we received from the remote agent - # is gone... Let's assign a new session... - session_list = [] - session_info = None + # Thus, let's ignore this session and check if there is another appropriate session in session_list + if session_info is not None: + session_list.remove(session_info) + session_info = None if not selected_session and not server_list: selected_session = { - 'server': 'no-X2Go-Server-available', - 'port': server_port, + u'server': u'no-X2Go-Server-available', + u'port': server_port, } # are we resuming a running/suspended session? @@ -1407,6 +1407,13 @@ class X2GoBroker(object): # session autologin feature if remote_agent and self.get_session_autologin(profile_id) and username: + # let's use the chosen server_name if remote_agent is reachable via SSH + if type(remote_agent) is types.DictType: + remote_agent = { + u'hostname': selected_session[u'server'], + u'port': selected_session[u'port'], + } + if not pubkey: # if the broker client has not provided a public SSH key, we will generate one # this is the OLD style of the auto login feature diff --git a/x2gobroker/tests/test_broker_agent.py b/x2gobroker/tests/test_broker_agent.py index 2bdab1e..ba349bc 100644 --- a/x2gobroker/tests/test_broker_agent.py +++ b/x2gobroker/tests/test_broker_agent.py @@ -20,6 +20,7 @@ import unittest import tempfile import copy +import time # Python X2GoBroker modules import x2gobroker.brokers.inifile_broker as inifile @@ -33,6 +34,7 @@ class TestX2GoBrokerAgent(unittest.TestCase): _save_local_broker_agent_call = x2gobroker.agent._call_local_broker_agent _save_remote_broker_agent_call = x2gobroker.agent._call_remote_broker_agent _save_portscan = x2gobroker.utils.portscan + _save_time_sleep = time.sleep def _call_testsuite_broker_agent(username, task, cmdline_args=[], remote_agent=None): @@ -60,16 +62,23 @@ class TestX2GoBrokerAgent(unittest.TestCase): return True, list_sessions elif task == 'suspendsession': - return True + return True, [] + + elif task == 'ping': + return True, [] return False, [] def _fake_portscan(addr, port=22): return True + def _fake_time_sleep(sec): + pass + x2gobroker.agent._call_local_broker_agent = _call_testsuite_broker_agent x2gobroker.agent._call_remote_broker_agent = _call_testsuite_broker_agent x2gobroker.utils.portscan = _fake_portscan + time.sleep = _fake_time_sleep _session_profiles = """ [DEFAULT] @@ -244,27 +253,39 @@ broker-agent-query-mode = SSH x2gobroker.agent._call_local_broker_agent = _save_local_broker_agent_call x2gobroker.agent._call_remote_broker_agent = _save_remote_broker_agent_call x2gobroker.utils.portscan = _save_portscan + time.sleep = _save_time_sleep def test_broker_agent_replies_with_offline_servers(self): _save_local_broker_agent_call = x2gobroker.agent._call_local_broker_agent _save_remote_broker_agent_call = x2gobroker.agent._call_remote_broker_agent _save_portscan = x2gobroker.utils.portscan + _save_time_sleep = time.sleep + self.tbarwos_session_suspended = False def _call_testsuite_broker_agent(username, task, cmdline_args=[], remote_agent=None): if task == 'listsessions': list_sessions = [] if username == 'foo4BS1': - list_sessions = ['30342|foo1S-50-1414759661_stDMATE_dp24|50|host3-with-session|S|2014-10-31T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|34|30003|-1|-1', + list_sessions = ['30342|foo4BS1-50-1414759661_stDMATE_dp24|50|host3-with-session|S|2014-10-31T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo4BS1|34|30003|-1|-1', ] elif username == 'foo4BS2': + list_sessions = ['30342|foo4BS2-50-1414759661_stDMATE_dp24|50|downhost1-with-session|S|2014-10-31T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo4BS2|34|30003|-1|-1', + ] + elif username == 'foo4BS3': + list_sessions = ['30342|foo1S-50-1414759661_stDMATE_dp24|50|downhost1-with-session|R|2014-10-31T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|34|30003|-1|-1', + '30342|foo1S-50-1414759661_stDMATE_dp24|50|host3-with-session|S|2014-10-30T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|1474|30003|-1|-1', + ] + elif username == 'foo4BS4': list_sessions = ['30342|foo1S-50-1414759661_stDMATE_dp24|50|downhost1-with-session|S|2014-10-31T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|34|30003|-1|-1', + '30342|foo1S-50-1414759661_stDMATE_dp24|50|host3-with-session|R|2014-10-30T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|1474|30003|-1|-1', ] return True, list_sessions elif task == 'suspendsession': - return True + self.tbarwos_session_suspended = True + return True, [] elif task == 'findbusyservers': busy_servers = [] @@ -274,14 +295,24 @@ broker-agent-query-mode = SSH '2:host2.internal', '1:host3.internal', ] - elif username == 'foo4BS1': + elif username in ('foo4BS1', 'foo4BS2', 'foo4BS3'): busy_servers = [ '2:downhost1-with-session.internal', '1:host2.internal', '3:host3-with-session.internal', ] + elif username in ('foo5BS1'): + busy_servers = [ + '2:downhost1-with-session.internal', + '1:host2.internal', + '3:host3-with-session.internal', + '0:host4.internal', + ] return True, busy_servers + elif task == 'ping': + return True, [] + return False, [] def _fake_portscan(addr, port=22): @@ -291,9 +322,13 @@ broker-agent-query-mode = SSH return False return True + def _fake_time_sleep(sec): + pass + x2gobroker.agent._call_local_broker_agent = _call_testsuite_broker_agent x2gobroker.agent._call_remote_broker_agent = _call_testsuite_broker_agent x2gobroker.utils.portscan = _fake_portscan + time.sleep = _fake_time_sleep _session_profiles = """ [DEFAULT] @@ -325,6 +360,13 @@ host = downhost1-with-session.internal, host2.internal, host3-with-session.inter broker-agent-query-mode = LOCAL broker-portscan-x2goservers = true +[testprofile5] +name = testprofile5 +host = downhost1-with-session.internal, host2.internal, host3-with-session.internal, host4.internal +broker-agent-query-mode = SSH +broker-portscan-x2goservers = true +broker-autologin = true + """ tf = tempfile.NamedTemporaryFile() print >> tf, _session_profiles @@ -353,7 +395,7 @@ broker-portscan-x2goservers = true while i < 10: _session4 = inifile_backend.select_session('testprofile4', username='foo4BS1') self.assertTrue ( _session4['server'] == 'host3-with-session.internal') - self.assertTrue ( _session4['session_info'] == '30342|foo1S-50-1414759661_stDMATE_dp24|50|host3-with-session|S|2014-10-31T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|34|30003|-1|-1' ) + self.assertTrue ( _session4['session_info'] == '30342|foo4BS1-50-1414759661_stDMATE_dp24|50|host3-with-session|S|2014-10-31T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo4BS1|34|30003|-1|-1' ) i += 1 i = 0 @@ -363,9 +405,34 @@ broker-portscan-x2goservers = true self.assertFalse ( _session4.has_key('session_info') ) i += 1 + i = 0 + while i < 10: + _session4 = inifile_backend.select_session('testprofile4', username='foo4BS3') + self.assertTrue ( _session4['server'] == 'host3-with-session.internal') + self.assertTrue ( _session4['session_info'] == '30342|foo1S-50-1414759661_stDMATE_dp24|50|host3-with-session|S|2014-10-30T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|1474|30003|-1|-1' ) + i += 1 + + i = 0 + while i < 10: + _session4 = inifile_backend.select_session('testprofile4', username='foo4BS4') + self.assertTrue ( _session4['server'] == 'host3-with-session.internal') + self.assertTrue ( _session4['session_info'] == '30342|foo1S-50-1414759661_stDMATE_dp24|50|host3-with-session|S|2014-10-30T13:47:41|c02c7bbe58677a2726f7e456cb398ae4|127.0.0.1|30001|30002|2014-10-31T13:47:43|foo1S|1474|30003|-1|-1' ) + self.assertTrue ( self.tbarwos_session_suspended ) + self.tbarwos_session_suspended = False + i += 1 + + i = 0 + while i < 10: + _session5 = inifile_backend.select_session('testprofile5', username='foo5BS1') + print _session5 + self.assertTrue ( _session5['server'] == 'host4.internal') + self.assertFalse ( _session5.has_key('session_info') ) + i += 1 + x2gobroker.agent._call_local_broker_agent = _save_local_broker_agent_call x2gobroker.agent._call_remote_broker_agent = _save_remote_broker_agent_call x2gobroker.utils.portscan = _save_portscan + time.sleep = _save_time_sleep def test_suite(): -- Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git