The branch, master has been updated via 9557b67570875897d1f45f61f174461c45b1a7c6 (commit) via d4054a17444c93618020c4412e8b49361371f3cf (commit) via 140299b062adce94b65dc10ac19bb97497af87cc (commit) via 3f3e1d0961d98a8a4b993efc0ed06b0295f6bcac (commit) via 3f866e07a2c228fd3681a011f49794b73b51692a (commit) from 8676299cde99da2c19307431c2a81f46b16b31dc (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 ----------------------------------------------------------------- commit 9557b67570875897d1f45f61f174461c45b1a7c6 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Mar 6 17:50:35 2013 +0100 Add algorithm to ,,normalize'' hostnames used in session profiles vs. those returned by the broker agent. (Fixes: #133). commit d4054a17444c93618020c4412e8b49361371f3cf Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Mar 6 17:49:03 2013 +0100 remove remnant traces of webpy engine (replaced by tornado httpd engine) commit 140299b062adce94b65dc10ac19bb97497af87cc Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Mar 6 17:48:03 2013 +0100 /debian/control: Build-Depend on python-paste, python-nose (testsuite needs them). commit 3f3e1d0961d98a8a4b993efc0ed06b0295f6bcac Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Mar 6 17:47:04 2013 +0100 Continue development... commit 3f866e07a2c228fd3681a011f49794b73b51692a Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Mar 6 15:39:37 2013 +0100 typo fix ----------------------------------------------------------------------- Summary of changes: debian/changelog | 11 +++ debian/control | 2 + sbin/x2gobroker-pubkeyauthorizer | 2 +- x2gobroker/__init__.py | 2 +- x2gobroker/brokers/base_broker.py | 29 +++++++- x2gobroker/tests/test_utils.py | 102 ++++++++++++++++++++++++++++ x2gobroker/tests/test_web_plain_inifile.py | 6 +- x2gobroker/utils.py | 45 ++++++++++++ 8 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 x2gobroker/tests/test_utils.py The diff of changes is: diff --git a/debian/changelog b/debian/changelog index 872f3aa..d8c0c3c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +x2gobroker (0.0.0.7-0~x2go1) UNRELEASED; urgency=low + + [ Mike Gabriel ] + * New upstream version (0.0.0.7): + - Add algorithm to ,,normalize'' hostnames used in session profiles + vs. those returned by the broker agent. (Fixes: #133). + * /debian/control: + + Build-Depend on python-paste, python-nose (testsuite needs them). + + -- Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Wed, 06 Mar 2013 17:45:40 +0100 + x2gobroker (0.0.0.6-0~x2go1) unstable; urgency=low [ Mike Gabriel ] diff --git a/debian/control b/debian/control index ece5439..79dc5cb 100644 --- a/debian/control +++ b/debian/control @@ -11,6 +11,8 @@ Build-Depends: dpkg-dev (>= 1.16.1~), python (>= 2.6.5-0~), python-setuptools, + python-nose, + python-paste, Standards-Version: 3.9.3 XS-Python-Version: >= 2.4 diff --git a/sbin/x2gobroker-pubkeyauthorizer b/sbin/x2gobroker-pubkeyauthorizer index c1e9f41..39440bb 100755 --- a/sbin/x2gobroker-pubkeyauthorizer +++ b/sbin/x2gobroker-pubkeyauthorizer @@ -36,7 +36,7 @@ import logging.config from pwd import getpwnam from grp import getgrnam -__VERSION__ = '0.0.0.6' +__VERSION__ = '0.0.0.7' __AUTHOR__ = 'Mike Gabriel (X2Go Project) <mike.gabriel@das-netzwerkteam.de>' PROG_NAME = os.path.basename(sys.argv[0]) diff --git a/x2gobroker/__init__.py b/x2gobroker/__init__.py index 2c644a2..6d877ca 100644 --- a/x2gobroker/__init__.py +++ b/x2gobroker/__init__.py @@ -18,5 +18,5 @@ # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. -__VERSION__ = '0.0.0.6' +__VERSION__ = '0.0.0.7' __AUTHOR__ = 'Mike Gabriel (X2Go Project) <mike.gabriel@das-netzwerkteam.de>' diff --git a/x2gobroker/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py index 9001039..081960f 100644 --- a/x2gobroker/brokers/base_broker.py +++ b/x2gobroker/brokers/base_broker.py @@ -813,10 +813,37 @@ class X2GoBroker(object): remote_agent_port = profile[u'sshport'] remote_agent = {u'hostname': remote_agent_server, u'port': remote_agent_port, } + # detect best X2Go server for this user if load balancing is configured if len(server_list) >= 2 and username: busy_servers = x2gobroker.agent.find_busy_servers(username=username, query_mode=agent_query_mode, remote_agent = remote_agent) + # when detecting the server load we have to support handling of differing subdomains (config + # file vs. server load returned by x2gobroker agent). Best approach: all members of a multi-node + # server farm either (a) do not have a subdomain in their hostname or (b) the subdomain is + # is identical. + + # Example: + # + # ts01, ts02 - hostnames as returned by agent + # ts01.intern, ts02.intern - hostnames configured in session profile option ,,host'' + # -> this will result in the subdomain .intern being stripped off from the hostnames before detecting + # the best server for this user + + ### NORMALIZE (=reduce to hostname only) X2Go server names (as found in config) if possible + server_list_normalized, subdomains_config = x2gobroker.utils.normalize_hostnames(server_list) + + ### NORMALIZE X2Go server names (as returned by x2gobroker agent)--only if the hostnames in the config share the same subdomain + if len(subdomains_config) == 1: + + busy_servers_normalized, subdomains_agent = x2gobroker.utils.normalize_hostnames(busy_servers) + if len(subdomains_agent) == 1: + + # all X2Go servers in the multi-node server farm are in the same DNS subdomain + # we can operate on hostname-only hostnames + server_list = server_list_normalized + busy_servers = busy_servers_normalized + for server in server_list: if server not in busy_servers.keys(): busy_servers[server] = 0 @@ -877,7 +904,7 @@ class X2GoBroker(object): query_mode=agent_query_mode, remote_agent=remote_agent, delay_deletion=20, - ), + ) return selected_session diff --git a/x2gobroker/tests/test_utils.py b/x2gobroker/tests/test_utils.py new file mode 100644 index 0000000..871dca7 --- /dev/null +++ b/x2gobroker/tests/test_utils.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2012 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de> +# +# X2Go Session Broker is free software; you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# X2Go Session Broker is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +import unittest +import tempfile + +# Python X2GoBroker modules +import x2gobroker.utils + +class TestX2GoBrokerUtils(unittest.TestCase): + + ### TEST FUNCTION: normalize_hostnames() with server lists (ListType) + + def test_normalize_hostnames_listtype(self): + + server_list = ['ts01', 'ts02', 'ts03',] + expected_server_list = ['ts01', 'ts02', 'ts03',] + server_list_n, subdomains = x2gobroker.utils.normalize_hostnames(server_list) + server_list_n.sort() + self.assertEqual(expected_server_list, server_list_n) + self.assertEqual([], subdomains) + + server_list = ['ts01.intern', 'ts02.intern', 'ts03.intern',] + expected_server_list = ['ts01', 'ts02', 'ts03',] + server_list_n, subdomains = x2gobroker.utils.normalize_hostnames(server_list) + server_list_n.sort() + self.assertEqual(expected_server_list, server_list_n) + self.assertEqual(['intern'], subdomains) + + server_list = ['ts01.intern', 'ts02.intern', 'ts03.extern',] + expected_server_list = ['ts01.intern', 'ts02.intern', 'ts03.extern',] + server_list_n, subdomains = x2gobroker.utils.normalize_hostnames(server_list) + server_list_n.sort() + subdomains.sort() + self.assertEqual(expected_server_list, server_list_n) + self.assertEqual(['extern', 'intern'], subdomains) + + server_tuple = ('ts01.intern', 'ts02.intern', 'ts03.extern',) + expected_server_list = ['ts01.intern', 'ts02.intern', 'ts03.extern',] + server_list_n, subdomains = x2gobroker.utils.normalize_hostnames(server_tuple) + server_list_n.sort() + subdomains.sort() + self.assertEqual(expected_server_list, server_list_n) + self.assertEqual(['extern', 'intern'], subdomains) + + ### TEST FUNCTION: normalize_hostnames() with server load (DictType) + + def test_normalize_hostnames_dicttype(self): + + server_load = {'ts01': 10, 'ts02': 20, 'ts03': 30,} + expected_server_load = {'ts01': 10, 'ts02': 20, 'ts03': 30,} + server_load_n, subdomains = x2gobroker.utils.normalize_hostnames(server_load) + sln_keys = server_load_n.keys() + esl_keys = expected_server_load.keys() + sln_keys.sort() + esl_keys.sort() + self.assertEqual(esl_keys, sln_keys) + self.assertEqual([], subdomains) + + server_load = {'ts01.intern': 10, 'ts02.intern': 20, 'ts03.intern': 30,} + expected_server_load = {'ts01': 10, 'ts02': 20, 'ts03': 30,} + server_load_n, subdomains = x2gobroker.utils.normalize_hostnames(server_load) + sln_keys = server_load_n.keys() + esl_keys = expected_server_load.keys() + sln_keys.sort() + esl_keys.sort() + self.assertEqual(esl_keys, sln_keys) + self.assertEqual(['intern'], subdomains) + + server_load = {'ts01.intern': 10, 'ts02.intern': 20, 'ts03.extern': 30,} + expected_server_load = {'ts01.intern': 10, 'ts02.intern': 20, 'ts03.extern': 30,} + server_load_n, subdomains = x2gobroker.utils.normalize_hostnames(server_load) + sln_keys = server_load_n.keys() + esl_keys = expected_server_load.keys() + sln_keys.sort() + esl_keys.sort() + subdomains.sort() + self.assertEqual(esl_keys, sln_keys) + self.assertEqual(['extern', 'intern'], subdomains) + + +def test_suite(): + from unittest import TestSuite, makeSuite + suite = TestSuite() + suite.addTest(makeSuite(TestX2GoBrokerUtils)) + return suite diff --git a/x2gobroker/tests/test_web_plain_inifile.py b/x2gobroker/tests/test_web_plain_inifile.py index 114e73f..f87f81b 100644 --- a/x2gobroker/tests/test_web_plain_inifile.py +++ b/x2gobroker/tests/test_web_plain_inifile.py @@ -21,14 +21,14 @@ import unittest import tempfile from paste.fixture import TestApp from nose.tools import * -import web +import tornado.wsgi # Python X2GoBroker modules import x2gobroker.defaults import x2gobroker.web.plain -urls = ( '/plain/(.*)', 'x2gobroker.web.plain.X2GoBrokerWeb',) -app = web.application(urls, globals()) +urls = ( ('/plain/(.*)', x2gobroker.web.plain.X2GoBrokerWeb,) ,) +application = tornado.wsgi.WSGIApplication(urls) x2gobroker.defaults.X2GOBROKER_CONFIG_DEFAULTS.update({'base': {'enable': True, },}) diff --git a/x2gobroker/utils.py b/x2gobroker/utils.py index 79f5ed3..0874cf5 100644 --- a/x2gobroker/utils.py +++ b/x2gobroker/utils.py @@ -23,6 +23,7 @@ import os import sys import types import locale +import netaddr import distutils.version def _checkConfigFileDefaults(data_structure): @@ -103,3 +104,47 @@ def compare_versions(version_a, op, version_b): return eval("ver_a %s ver_b" % op) + +def normalize_hostnames(servers): + """\ + """ + + # test the data type of servers + arg_is_dict = False + servers_normalized = [] + if type(servers) is types.DictType: + arg_is_dict = True + servers_normalized = {} + elif type(servers) is types.TupleType: + servers=list(servers) + elif type(servers) not in (types.ListType, types.TupleType): + raise ValueError('only lists, tuples and dictionaries are valid for x2gobroker.utils.normalize_hostnames()') + + subdomains = [] + for server in servers: + + # do not deal with IPv4 or IPv6 addresses + if netaddr.valid_ipv4(server) or netaddr.valid_ipv6(server): + continue + else: + _server = server + if '.' not in _server: + _server += '.' + hostname, subdomain = _server.split('.', 1) + if arg_is_dict: + servers_normalized[hostname] = servers[server] + else: + servers_normalized.append(hostname) + + # collect the list of subdomains used in all server names + if subdomain and subdomain not in subdomains: + subdomains.append(subdomain) + # stop processing if we have more than one subdomain + if len(subdomains) > 1: + break + + # return the original servers dict/list/tuple + if len(subdomains) > 1: + servers_normalized = servers + + return servers_normalized, subdomains hooks/post-receive -- x2gobroker.git (HTTP(S) Session broker for X2Go) 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 "x2gobroker.git" (HTTP(S) Session broker for X2Go).