This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit bae0d29c2fd7cb317f39271590aa5f82619a21b9 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Fri Nov 28 15:00:39 2014 +0100 Enable basic/random load-balancing for UCCS broker frontend. Make UCCS frontend aware of host session profile options of the form "host=<fqdn> (<ipaddr>:<port>). --- bin/x2gobroker-ssh | Bin 10461 -> 10328 bytes debian/changelog | 3 + x2gobroker/brokers/base_broker.py | 123 +++++++++++++++++++++++++------------ x2gobroker/web/uccs.py | 27 +++++--- 4 files changed, 104 insertions(+), 49 deletions(-) diff --git a/bin/x2gobroker-ssh b/bin/x2gobroker-ssh index 03444ca..10f24a3 100755 Binary files a/bin/x2gobroker-ssh and b/bin/x2gobroker-ssh differ diff --git a/debian/changelog b/debian/changelog index 4659fe8..edd9382 100644 --- a/debian/changelog +++ b/debian/changelog @@ -199,6 +199,9 @@ x2gobroker (0.0.3.0-0x2go1) UNRELEASED; urgency=low - Properly set (/var)/run/x2gobroker directory permissions when started via systemd. - Fix privilege check for the broker daemon's log directory. + - Enable basic/random load-balancing for UCCS broker frontend. Make UCCS + frontend aware of host session profile options of the form + "host=<fqdn> (<ipaddr>:<port>). * 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/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py index fc5082c..880e1d7 100644 --- a/x2gobroker/brokers/base_broker.py +++ b/x2gobroker/brokers/base_broker.py @@ -243,6 +243,19 @@ class X2GoBroker(object): """ return [] + def get_profile_ids_for_user(self, username): + """\ + Retrieve the list of session profile IDs for a given user. + + @param username: query profile id list for this user + @type username: C{unicode} + + @return: list of profile IDs + @rtype: C{list} + + """ + return [ id for id in self.get_profile_ids() if self.check_profile_acls(username, self.get_profile_acls(id)) ] + def get_profile_defaults(self): """\ Get the session profile defaults, i.e. profile options that all @@ -992,23 +1005,41 @@ class X2GoBroker(object): return remote_agent - def list_profiles(self, username): + def get_profile_for_user(self, profile_id, username, broker_frontend=None): """\ - Retrieve a list of available session profiles for the authenticated user. - - @param username: query session list for this user + Expect a profile id and perform some checks and preparations to + make it ready for exporting to a broker client: + + - drop internal host=<hostname> and sshport=<port> keys from the + profile, broker clients cannot handle those + - replace BROKER_USER by the name of the authenticated user + - test if autologin is possible + - fix rootless session profile option for non-desktop sessions + - perform an ACL check (return C{None} if it fails) + - query a remote agent (if configured) to check if we have + running / suspended sessions on the remote X2Go Server + + @param profile_id: ID of a valid session profile + @type profile_id: C{unicode} + @param username: prepare session profile for this (authenticated) user @type username: C{unicode} + @param broker_frontend: some broker frontend (e.g. UCCS) require special treatment + by this method + @type broker_frontend: C{unicode} - return: list of profile dictionaries + return: session profile as a dictionary (ready for sending out to a broker client) rtype: C{dict} """ - list_of_profiles = {} - for profile_id in self.get_profile_ids(): - profile = self.get_profile(profile_id) + profile = self.get_profile(profile_id) + + acls = self.get_profile_acls(profile_id) + if self.check_profile_acls(username, acls): for key in profile.keys(): - if key.startswith('host='): + if key.startswith('host=') and broker_frontend != 'uccs': + del profile[key] + if key.startswith('sshport=') and broker_frontend != 'uccs': del profile[key] if key == 'user' and profile[key] == 'BROKER_USER': profile[key] = unicode(username) @@ -1021,40 +1052,54 @@ class X2GoBroker(object): if profile['command'] in x2gobroker.defaults.X2GO_DESKTOP_SESSIONS: profile['rootless'] = False - acls = self.get_profile_acls(profile_id) + remote_agent = self.get_remote_agent(profile_id) + agent_query_mode = ( remote_agent == u'LOCAL') and u'LOCAL' or u'SSH' + if remote_agent: + success, running_sessions, suspended_sessions = x2gobroker.agent.has_sessions(username, remote_agent=remote_agent) + try: + success, running_sessions, suspended_sessions = x2gobroker.agent.has_sessions(username, remote_agent=remote_agent) + if running_sessions: + logger_broker.debug('base_broker.X2GoBroker.list_profiles(): found running sessions on host(s): {hosts}'.format(hosts=', '.join(running_sessions))) + if suspended_sessions: + logger_broker.debug('base_broker.X2GoBroker.list_profiles(): found running sessions on host(s): {hosts}'.format(hosts=', '.join(suspended_sessions))) + suspended_matching_hostnames = x2gobroker.utils.matching_hostnames(profile['host'], suspended_sessions) + running_matching_hostnames = x2gobroker.utils.matching_hostnames(profile['host'], running_sessions) + if suspended_matching_hostnames: + profile['status'] = u'S' + profile['host'] = [suspended_matching_hostnames[0]] + elif running_matching_hostnames: + profile['status'] = u'R' + profile['host'] = [running_matching_hostnames[0]] + else: + profile['host'] = [profile['host'][0]] + + if profile.has_key('status') and profile['status']: + logger_broker.debug('base_broker.X2GoBroker.list_profiles(): marking session profile {name} as {status}'.format(name=profile['name'], status=profile['status'])) - if self.check_profile_acls(username, acls): + except x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException: + pass + else: + profile['host'] = [profile['host'][0]] - remote_agent = self.get_remote_agent(profile_id) - agent_query_mode = ( remote_agent == u'LOCAL') and u'LOCAL' or u'SSH' - if remote_agent: + return profile + else: + return None - success, running_sessions, suspended_sessions = x2gobroker.agent.has_sessions(username, remote_agent=remote_agent) - try: - success, running_sessions, suspended_sessions = x2gobroker.agent.has_sessions(username, remote_agent=remote_agent) - if running_sessions: - logger_broker.debug('base_broker.X2GoBroker.list_profiles(): found running sessions on host(s): {hosts}'.format(hosts=', '.join(running_sessions))) - if suspended_sessions: - logger_broker.debug('base_broker.X2GoBroker.list_profiles(): found running sessions on host(s): {hosts}'.format(hosts=', '.join(suspended_sessions))) - suspended_matching_hostnames = x2gobroker.utils.matching_hostnames(profile['host'], suspended_sessions) - running_matching_hostnames = x2gobroker.utils.matching_hostnames(profile['host'], running_sessions) - if suspended_matching_hostnames: - profile['status'] = u'S' - profile['host'] = [suspended_matching_hostnames[0]] - elif running_matching_hostnames: - profile['status'] = u'R' - profile['host'] = [running_matching_hostnames[0]] - else: - profile['host'] = [profile['host'][0]] - - if profile.has_key('status') and profile['status']: - logger_broker.debug('base_broker.X2GoBroker.list_profiles(): marking session profile {name} as {status}'.format(name=profile['name'], status=profile['status'])) - - except x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException: - pass - else: - profile['host'] = [profile['host'][0]] + def list_profiles(self, username): + """\ + Retrieve a list of available session profiles for the authenticated user. + + @param username: query session profile list for this user + @type username: C{unicode} + return: list of profile dictionaries + rtype: C{dict} + + """ + list_of_profiles = {} + for profile_id in self.get_profile_ids_for_user(username): + profile = self.get_profile_for_user(profile_id, username) + if profile: list_of_profiles.update({profile_id: profile, }) return list_of_profiles diff --git a/x2gobroker/web/uccs.py b/x2gobroker/web/uccs.py index dd138e1..deea684 100644 --- a/x2gobroker/web/uccs.py +++ b/x2gobroker/web/uccs.py @@ -21,6 +21,7 @@ import re import base64 import datetime import types +import random import tornado.web # Python X2Go Broker modules @@ -141,33 +142,39 @@ class X2GoBrokerWebAPI(tornado.web.RequestHandler): output = '' - profiles = self.broker_backend.list_profiles(username) + profile_ids = self.broker_backend.get_profile_ids_for_user(username) urlbase = self.broker_backend.get_global_value('my-uccs-url-base').rstrip('/') ms = x2gobroker.uccsjson.ManagementServer('{urlbase}/uccs/{backend}/'.format(urlbase=urlbase, backend=backend), 'X2Go Session Broker') - profile_ids = profiles.keys() profile_ids.sort() for profile_id in profile_ids: - hosts = profiles[profile_id][u'host'] + profile = self.broker_backend.get_profile_for_user(profile_id, username, broker_frontend='uccs') + hosts = profile[u'host'] if type(hosts) == types.UnicodeType: hosts = [hosts] - if profiles[profile_id][u'directrdp']: + if profile[u'directrdp']: ts = x2gobroker.uccsjson.RDPServer( host='{hostname}'.format(hostname=hosts[0]), - name=profiles[profile_id][u'name'], - username=profiles[profile_id][u'user'], + name=profile[u'name'], + username=profile[u'user'], ) ts.set_domain('LOCAL') else: + _hostname = random.choice(hosts) + _port = profile[u'sshport'] + if profile.has_key('sshport={hostname}'.format(hostname=_hostname)): + _port = profile['sshport={hostname}'.format(hostname=_hostname)] + if profile.has_key('host={hostname}'.format(hostname=_hostname)): + _hostname = profile['host={hostname}'.format(hostname=_hostname)] ts = x2gobroker.uccsjson.X2GoServer( - host='{hostname}:{port}'.format(hostname=hosts[0], port=profiles[profile_id][u'sshport']), - name=profiles[profile_id][u'name'], - username=profiles[profile_id][u'user'], + host='{hostname}:{port}'.format(hostname=_hostname, port=_port), + name=profile[u'name'], + username=profile[u'user'], ) - ts.set_session_type(profiles[profile_id]['command']) + ts.set_session_type(profile['command']) ms.add_terminalserver(ts) ms.set_default(ts.Name) -- Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git