[X2Go-Commits] x2gobroker.git - statusflag (branch) updated: 0.0.0.6-5-g9557b67

X2Go dev team git-admin at x2go.org
Tue Jun 4 21:09:56 CEST 2013


The branch, statusflag has been updated
       via  9557b67570875897d1f45f61f174461c45b1a7c6 (commit)
      from  d4054a17444c93618020c4412e8b49361371f3cf (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                  |    3 +-
 x2gobroker/brokers/base_broker.py |   27 ++++++++++
 x2gobroker/tests/test_utils.py    |  102 +++++++++++++++++++++++++++++++++++++
 x2gobroker/utils.py               |   45 ++++++++++++++++
 4 files changed, 176 insertions(+), 1 deletion(-)
 create mode 100644 x2gobroker/tests/test_utils.py

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index a5b6be6..d8c0c3c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,8 @@ x2gobroker (0.0.0.7-0~x2go1) UNRELEASED; urgency=low
 
   [ Mike Gabriel ]
   * New upstream version (0.0.0.7):
-    Continue development...
+    - 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).
 
diff --git a/x2gobroker/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py
index 2b10bda..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
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 at 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/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).




More information about the x2go-commits mailing list