This is an automated email from the git hooks/post-receive script. x2go pushed a change to branch master in repository x2gobroker. from d7925d1 Makefile.docupload; Update DOC_PATH. A symlink from python-x2gobroker/ to x2gobroker/ exists on the server. new 6956eb8 various fixes (rebase them all) new eefaed4 x2gobroker/defaults.py: Provide API documentation for global defaults. new 80ab975 etc/x2gobroker.conf: Fix the load_factor formula. new 623cf13 x2gobroker/loadchecker.py: Provide/improve API documentation for the load checker. new 9f9e5d6 x2gobroker/utils.py: Provide/improve API documentation for our utility functions. new 87e07e3 x2gobroker/agent.py: Avoid zombie x2gobroker-agent processes by terminating the process and emptying the communication buffers. new c3067f0 bin/x2gobroker: If binding the http server fails, a non-zero exit code should be returned. (Fixes: #1013). The 7 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Summary of changes: bin/x2gobroker | 6 +- debian/changelog | 2 + docs/Makefile | 3 + etc/x2gobroker.conf | 2 +- x2gobroker/agent.py | 2 + x2gobroker/authmechs/none_authmech.py | 2 +- x2gobroker/defaults.py | 94 +++++++++++++++++---------- x2gobroker/loadchecker.py | 115 ++++++++++++++++++++++++++++++---- x2gobroker/utils.py | 99 ++++++++++++++++++++++++++++- 9 files changed, 277 insertions(+), 48 deletions(-) -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit 6956eb837b8d2d91f309eb411ffa036f02d41429 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Sep 12 16:51:03 2018 +0200 various fixes (rebase them all) --- x2gobroker/authmechs/none_authmech.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x2gobroker/authmechs/none_authmech.py b/x2gobroker/authmechs/none_authmech.py index f4ce316..147cef6 100644 --- a/x2gobroker/authmechs/none_authmech.py +++ b/x2gobroker/authmechs/none_authmech.py @@ -30,7 +30,7 @@ class X2GoBrokerAuthMech(object): networks with non-trusted hosts. **NOTE:** The broker will not be able to distinguish between users when delivering - available servers and session to the user's X2Go Client application. + available servers and session profiles to the user's X2Go Client application. """ def authenticate(self, username, password, **kwargs): -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit eefaed4187faa6af33c15e4622a75039845a4ab9 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Thu Sep 13 08:22:52 2018 +0200 x2gobroker/defaults.py: Provide API documentation for global defaults. --- docs/Makefile | 3 ++ x2gobroker/defaults.py | 94 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 64 insertions(+), 33 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 9e23aa9..f97332f 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,6 +1,9 @@ # Makefile for Sphinx documentation # +# required in the Python X2Go Broker code... e.g. in x2gobroker/defaults.py +SPHINX_API_DOCUMENTATION_BUILD = yes + # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build diff --git a/x2gobroker/defaults.py b/x2gobroker/defaults.py index 0196496..1615354 100644 --- a/x2gobroker/defaults.py +++ b/x2gobroker/defaults.py @@ -17,6 +17,18 @@ # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +""" +X2Go Session Brokers uses many hard-coded defaults, that can be overridden in various ways: + + * environment variables of the same name as the variable name in Python + * for **SysV init system**: environment variables set in a default configuration + file under ``/etc/default``; normally the naming scheme is + ``/etc/default/<executable-name>`` + * for **systemd init system**: in the file ``/etc/x2go/broker/defaults.conf``: + this file should be installed on your system, the file needs to be provided + in INI file format +""" + # modules import os import uuid @@ -29,10 +41,20 @@ from x2gobroker.loggers import iniconfig_loaded if iniconfig_loaded: from x2gobroker.loggers import iniconfig, iniconfig_section -X2GOBROKER_USER = pwd.getpwuid(os.geteuid())[0] -X2GOBROKER_GROUP = grp.getgrgid(pwd.getpwuid(os.geteuid())[3])[0] +X2GOBROKER_USER = '<some-user>' +"""The (system) user, X2Go Session Broker runs under. Whether this is a system user or e.g. your own user account depends on what component of the broker is used.""" +if 'SPHINX_API_DOCUMENTATION_BUILD' in os.environ.keys(): + X2GOBROKER_USER = pwd.getpwuid(os.geteuid())[0] + +X2GOBROKER_GROUP = '<some-group>' +"""The (system) group, X2Go Session Broker runs under. Whether this is a system user or e.g. the x2gobroker-users group is dependent on what component of the broker is used.""" +if 'SPHINX_API_DOCUMENTATION_BUILD' in os.environ.keys(): + X2GOBROKER_GROUP = grp.getgrgid(pwd.getpwuid(os.geteuid())[3])[0] + os.environ['HOME'] = pwd.getpwuid(os.geteuid())[5] +X2GOBROKER_AGENT_USER="x2gobroker" +"""The system user to use when launching X2Go Broker Agent on remote X2Go Servers.""" if 'X2GOBROKER_DAEMON_GROUP' in os.environ: X2GOBROKER_DAEMON_GROUP=os.environ['X2GOBROKER_DAEMON_GROUP'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DAEMON_GROUP'): @@ -47,13 +69,13 @@ elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_AG X2GOBROKER_AGENT_USER=iniconfig.get(iniconfig_section, 'X2GOBROKER_AGENT_USER') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_AGENT_USER'): X2GOBROKER_AGENT_USER=iniconfig.get('common', 'X2GOBROKER_AGENT_USER') -else: - X2GOBROKER_AGENT_USER="x2gobroker" ### ### dynamic default values, influencable through os.environ... ### +X2GOBROKER_DEBUG_INTERACTIVELY = False +"""When set to ``True``, the X2Go Broker component this parameter is set for, runs in foreground and debugging mode.""" if 'X2GOBROKER_DEBUG' in os.environ: X2GOBROKER_DEBUG = ( os.environ['X2GOBROKER_DEBUG'].lower() in ('1', 'on', 'true', 'yes', ) ) elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DEBUG'): @@ -68,8 +90,7 @@ elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DE X2GOBROKER_DEBUG_INTERACTIVELY=iniconfig.get(iniconfig_section, 'X2GOBROKER_DEBUG_INTERACTIVELY') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_DEBUG_INTERACTIVELY'): X2GOBROKER_DEBUG_INTERACTIVELY=iniconfig.get('common', 'X2GOBROKER_DEBUG_INTERACTIVELY') -else: - X2GOBROKER_DEBUG_INTERACTIVELY = False + if 'X2GOBROKER_TESTSUITE' in os.environ: X2GOBROKER_TESTSUITE = ( os.environ['X2GOBROKER_TESTSUITE'].lower() in ('1', 'on', 'true', 'yes', ) ) elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_TESTSUITE'): @@ -89,94 +110,95 @@ if X2GOBROKER_TESTSUITE: logger_access.setLevel(logging.CRITICAL) logger_error.setLevel(logging.CRITICAL) +X2GOBROKER_CONFIG = "/etc/x2go/x2gobroker.conf" +"""Location of X2Go Broker\'s global configuration file.""" if 'X2GOBROKER_CONFIG' in os.environ: X2GOBROKER_CONFIG = os.environ['X2GOBROKER_CONFIG'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_CONFIG'): X2GOBROKER_CONFIG=iniconfig.get(iniconfig_section, 'X2GOBROKER_CONFIG') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_CONFIG'): X2GOBROKER_CONFIG=iniconfig.get('common', 'X2GOBROKER_CONFIG') -else: - X2GOBROKER_CONFIG = "/etc/x2go/x2gobroker.conf" +X2GOBROKER_SESSIONPROFILES = "/etc/x2go/broker/x2gobroker-sessionprofiles.conf" +"""Location of the INI file based broker backend \'s session profiles configuration file.""" if 'X2GOBROKER_SESSIONPROFILES' in os.environ: X2GOBROKER_SESSIONPROFILES = os.environ['X2GOBROKER_SESSIONPROFILES'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_SESSIONPROFILES'): X2GOBROKER_SESSIONPROFILES=iniconfig.get(iniconfig_section, 'X2GOBROKER_SESSIONPROFILES') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_SESSIONPROFILES'): X2GOBROKER_SESSIONPROFILES=iniconfig.get('common', 'X2GOBROKER_SESSIONPROFILES') -else: - X2GOBROKER_SESSIONPROFILES = "/etc/x2go/broker/x2gobroker-sessionprofiles.conf" +X2GOBROKER_AGENT_CMD = "/usr/lib/x2go/x2gobroker-agent" +"""Path to the X2Go Broker Agent executable on remote X2Go Servers.""" if 'X2GOBROKER_AGENT_CMD' in os.environ: X2GOBROKER_AGENT_CMD = os.environ['X2GOBROKER_AGENT_CMD'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_AGENT_CMD'): X2GOBROKER_AGENT_CMD=iniconfig.get(iniconfig_section, 'X2GOBROKER_AGENT_CMD') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_AGENT_CMD'): X2GOBROKER_AGENT_CMD=iniconfig.get('common', 'X2GOBROKER_AGENT_CMD') -else: - X2GOBROKER_AGENT_CMD = "/usr/lib/x2go/x2gobroker-agent" +if os.path.isdir('/run/x2gobroker'): + RUNDIR = '/run' +else: + RUNDIR = '/var/run/x2gobroker' +X2GOBROKER_AUTHSERVICE_SOCKET="{run}/x2gobroker/x2gobroker-authservice.socket".format(run=RUNDIR) +"""Location of the X2Go Broker Auth Service's authentication socket file.""" if 'X2GOBROKER_AUTHSERVICE_SOCKET' in os.environ: X2GOBROKER_AUTHSERVICE_SOCKET=os.environ['X2GOBROKER_AUTHSERVICE_SOCKET'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_AUTHSERVICE_SOCKET'): X2GOBROKER_AUTHSERVICE_SOCKET=iniconfig.get(iniconfig_section, 'X2GOBROKER_AUTHSERVICE_SOCKET') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_AUTHSERVICE_SOCKET'): X2GOBROKER_AUTHSERVICE_SOCKET=iniconfig.get('common', 'X2GOBROKER_AUTHSERVICE_SOCKET') -else: - if os.path.isdir('/run/x2gobroker'): - RUNDIR = '/run' - else: - RUNDIR = '/var/run/x2gobroker' - X2GOBROKER_AUTHSERVICE_SOCKET="{run}/x2gobroker/x2gobroker-authservice.socket".format(run=RUNDIR) +if os.path.isdir('/run/x2gobroker'): + RUNDIR = '/run' +else: + RUNDIR = '/var/run/x2gobroker' +X2GOBROKER_LOADCHECKER_SOCKET="{run}/x2gobroker/x2gobroker-loadchecker.socket".format(run=RUNDIR) +"""Location of the X2Go Broker Load Checker's communication socket file.""" if 'X2GOBROKER_LOADCHECKER_SOCKET' in os.environ: X2GOBROKER_LOADCHECKER_SOCKET=os.environ['X2GOBROKER_LOADCHECKER_SOCKET'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_LOADCHECKER_SOCKET'): X2GOBROKER_LOADCHECKER_SOCKET=iniconfig.get(iniconfig_section, 'X2GOBROKER_LOADCHECKER_SOCKET') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_LOADCHECKER_SOCKET'): X2GOBROKER_LOADCHECKER_SOCKET=iniconfig.get('common', 'X2GOBROKER_LOADCHECKER_SOCKET') -else: - if os.path.isdir('/run/x2gobroker'): - RUNDIR = '/run' - else: - RUNDIR = '/var/run/x2gobroker' - X2GOBROKER_LOADCHECKER_SOCKET="{run}/x2gobroker/x2gobroker-loadchecker.socket".format(run=RUNDIR) +X2GOBROKER_DEFAULT_BACKEND = "inifile" +"""The broker backend to use by default.""" if 'X2GOBROKER_DEFAULT_BACKEND' in os.environ: X2GOBROKER_DEFAULT_BACKEND = os.environ['X2GOBROKER_DEFAULT_BACKEND'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DEFAULT_BACKEND'): X2GOBROKER_DEFAULT_BACKEND=iniconfig.get(iniconfig_section, 'X2GOBROKER_DEFAULT_BACKEND') elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_DEFAULT_BACKEND'): X2GOBROKER_DEFAULT_BACKEND=iniconfig.get('common', 'X2GOBROKER_DEFAULT_BACKEND') -else: - X2GOBROKER_DEFAULT_BACKEND = "inifile" + +DAEMON_BIND_ADDRESS = "" +"""Bind address for the X2Go Session Broker standalone daemon.""" if 'DAEMON_BIND_ADDRESS' in os.environ: DAEMON_BIND_ADDRESS = os.environ['DAEMON_BIND_ADDRESS'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'DAEMON_BIND_ADDRESS'): DAEMON_BIND_ADDRESS = iniconfig.get(iniconfig_section, 'DAEMON_BIND_ADDRESS') elif iniconfig_loaded and iniconfig.has_option('daemon', 'DAEMON_BIND_ADDRESS'): DAEMON_BIND_ADDRESS = iniconfig.get('daemon', 'DAEMON_BIND_ADDRESS') -else: - DAEMON_BIND_ADDRESS = "" +X2GOBROKER_SSL_CERTFILE = "" +"""Path to the SSL/TLS public certificate file.""" if 'X2GOBROKER_SSL_CERTFILE' in os.environ: X2GOBROKER_SSL_CERTFILE = os.environ['X2GOBROKER_SSL_CERTFILE'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_SSL_CERTFILE'): X2GOBROKER_SSL_CERTFILE = iniconfig.get(iniconfig_section, 'X2GOBROKER_SSL_CERTFILE') elif iniconfig_loaded and iniconfig.has_option('daemon', 'X2GOBROKER_SSL_CERTFILE'): X2GOBROKER_SSL_CERTFILE = iniconfig.get('daemon', 'X2GOBROKER_SSL_CERTFILE') -else: - X2GOBROKER_SSL_CERTFILE = "" +X2GOBROKER_SSL_KEYFILE = "" +"""Path to the SSL/TLS secret key file.""" if 'X2GOBROKER_SSL_KEYFILE' in os.environ: X2GOBROKER_SSL_KEYFILE = os.environ['X2GOBROKER_SSL_KEYFILE'] elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_SSL_KEYFILE'): X2GOBROKER_SSL_KEYFILE = iniconfig.get(iniconfig_section, 'X2GOBROKER_SSL_KEYFILE') elif iniconfig_loaded and iniconfig.has_option('daemon', 'X2GOBROKER_SSL_KEYFILE'): X2GOBROKER_SSL_KEYFILE = iniconfig.get('daemon', 'X2GOBROKER_SSL_KEYFILE') -else: - X2GOBROKER_SSL_KEYFILE = "" ### ### static / hard-coded defaults @@ -189,6 +211,7 @@ else: # the home directory of the user that the daemon/cgi runs as X2GOBROKER_HOME = os.path.normpath(os.path.expanduser('~{broker_uid}'.format(broker_uid=X2GOBROKER_DAEMON_USER))) +"""Home directory of the user that an X2Go Broker component runs under.""" # defaults for X2Go Sessino Broker configuration file X2GOBROKER_CONFIG_DEFAULTS = { @@ -258,6 +281,8 @@ X2GOBROKER_CONFIG_DEFAULTS = { 'load-checker': True, }, } +"""Defaults of the global configuration file, see ``X2GOBROKER_CONFIG``.""" + X2GO_DESKTOP_SESSIONS= [ 'KDE', @@ -273,6 +298,7 @@ X2GO_DESKTOP_SESSIONS= [ 'OPENBOX', 'XDMCP', ] +"""Desktop environment session types supported by X2Go.""" # defaults for X2Go Sessino Broker session profiles file X2GOBROKER_SESSIONPROFILE_DEFAULTS = { @@ -323,5 +349,7 @@ X2GOBROKER_SESSIONPROFILE_DEFAULTS = { 'acl-any-order': 'deny-allow', }, } +"""Default setting of a broker'ish session profile.""" -X2GOBROKER_LATEST_UCCS_API_VERSION = 5 \ No newline at end of file +X2GOBROKER_LATEST_UCCS_API_VERSION = 5 +"""Latest known API of the UCCS protocol that we support.""" -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit 80ab975dddf88d9c3c5b18bbc255d7df6c06f28c Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Thu Sep 13 08:40:53 2018 +0200 etc/x2gobroker.conf: Fix the load_factor formula. --- etc/x2gobroker.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/x2gobroker.conf b/etc/x2gobroker.conf index 7ba70be..6501458 100644 --- a/etc/x2gobroker.conf +++ b/etc/x2gobroker.conf @@ -271,7 +271,7 @@ # The load factor calculation uses this algorithm: # # ( memAvail/1000 ) * numCPUs * typeCPUs -# load-factor = -------------------------------------- +# load-factor = -------------------------------------- + 1 # loadavg*100 * numSessions # # (memAvail in MByte, typeCPUs in MHz, loadavg is (system load *100 + 1) as -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit 623cf13fb17dc077a5dd6a9ebe39f6a824720b11 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Thu Sep 13 09:08:36 2018 +0200 x2gobroker/loadchecker.py: Provide/improve API documentation for the load checker. --- x2gobroker/loadchecker.py | 115 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 11 deletions(-) diff --git a/x2gobroker/loadchecker.py b/x2gobroker/loadchecker.py index ed1e686..5683555 100644 --- a/x2gobroker/loadchecker.py +++ b/x2gobroker/loadchecker.py @@ -18,6 +18,42 @@ # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +"""\ +The X2Go Broker Load Checker is an auxiliary X2Go Session Broker service +that checks the load on associated X2Go Servers in regular intervals. + +The load of an X2Go Server gets checked by the Load Checker, if + + * an X2Go Server is part of a multi-server session profile + * the remote X2Go Server can be queried via X2Go Broker Agent + * the session profile (or the broker globally) is configured for + background load checking (see global config parameter: ``load-checker`` + in ``/etc/x2go/x2gobroker.conf`` + +In non-load-checker setups, multi-server session profiles perform a check +on all configured servers during the login phase of a user. On big server +farms, this check-them-all call to all members of the X2Go Server farm +can be really time consuming. + +The solution is to run the X2Go Broker Load Checker service on the broker +host and let it query server availability and load in regular intervals. +It collects the server metrics and stores them in memory. If the broker +receives a :func:`select_session() +<x2gobroker.brokers.base.X2GoBroker.select_session()>` request from an +X2Go client application, it will then negotiate with the load checker to +work out, what X2Go Server is best for this incoming request. + +On the X2Go Servers, the X2Go Broker Agent calculates a ``load_factor`` that +gets passed back to the X2Go Broker Load Checker when queried:: + + + ( memAvail/1000 ) * numCPUs * typeCPUs + load-factor = -------------------------------------- + 1 + loadavg*100 * numSessions + + +""" + import threading import time import copy @@ -30,6 +66,39 @@ from x2gobroker.loggers import logger_broker def check_load(backend, profile_id, hostname=None): + """\ + This function gets called from the broker daemon's side whenever the + broker needs information about associated X2Go Servers. It represents + the client-side of the load checking process in X2Go Session Broker. + + It either sends a one liner 3-tuple:: + + <backend>\\r<profile_id>\\r<hostname>\\n + + or a one liner 2-tuple:: + + <backend>\\r<profile_id>\\n + + to the ``X2GOBROKER_LOADCHECKER_SOCKET`` (see + :mod:`x2gobroker.defaults`) and expects a number (if the hostname was + included in the query) or a Python dictionary (if only ``backend`` + and ``profile_id`` had been given) as return value: the load + factor(s) + + :param backend: the broker backend in use + :type backend: ``str`` + :param profile_id: the session profile's ID + :type profile_id: ``str`` + :param hostname: the X2Go Server's hostname as shown in + ``x2golistsessions``'s output + :type hostname: ``str`` + + :returns: either the load factor of the asked for server (as ``int``) or + the load factors (as ``dict``) of all server members of the given session profile + server + :rtype: ``int`` or ``dict`` + + """ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) logger_broker.debug('loadchecker.check_load(): connecting to load checker service socket {socket}'.format(socket=x2gobroker.defaults.X2GOBROKER_LOADCHECKER_SOCKET)) try: @@ -89,13 +158,27 @@ def check_load(backend, profile_id, hostname=None): class LoadChecker(threading.Thread): - + """\ + The :class:`LoadChecker` class provides the functionality of setting up + a load checker service. It is the brain of the ``x2gobroker-loadchecker`` + executable. + + With it you can instantiate a new LoadChecker object for querying + remote X2Go Broker Agent instances about server/system load, CPU + usage, etc. in regular intervals. + + :param config_file: global ``x2gobroker`` config file + :type config_file: a :mod:`configparser` compliant ``<obj>`` + :param config_defaults: default (hard-coded) configuration parameters + for all parameters missing in the ``config_file`` + :type config_defaults: ``dict`` + :param logger: a :mod:`logging` instance + :type logger: ``<obj>`` + :param kwargs: Any other parameter (for future features' compatibility, all ignored for now) + :type kwargs: ``dict`` + + """ def __init__(self, config_file=None, config_defaults=None, logger=None, **kwargs): - """\ - Initialize a new LoadChecker instance for querying remote X2Go Broker Agent instances - about server/system load, CPU usage, etc. - - """ self.logger = logger self.config_file = config_file @@ -111,7 +194,7 @@ class LoadChecker(threading.Thread): def get_server_load(self, backend, profile_id, hostname): """\ - Retrieve system load for a given server (via broker backend, + Retrieve system load factor for a given server (via broker backend, profile ID and hostname). :param backend: broker backend to query. @@ -132,15 +215,15 @@ class LoadChecker(threading.Thread): def get_profile_load(self, backend, profile_id): """\ - Retrieve system load for all servers for a given profile ID (and a given - broker backend). + Retrieve system load factors for all member servers of the given + profile ID (and the given broker backend). :param backend: broker backend to query. :type backend: ``str`` :param profile_id: profile ID of the session profile to query :type profile_id: ``str`` - :returns: load factor of the given server (or None if an error occurs) + :returns: load factors of the given profile ID (or None if an error occurs) :rtype: ``dict`` """ @@ -151,7 +234,10 @@ class LoadChecker(threading.Thread): def loadchecker(self): """\ - This is the actual thread runner that queries configured / available X2Go Broker Agents in regular + This is the actual thread runner of the :class:`LoadChecker`` + class. + + It queries configured / available X2Go Broker Agents in regular intervals about system load, CPU types and usage. """ @@ -241,4 +327,11 @@ class LoadChecker(threading.Thread): time_to_sleep = 0 def stop_thread(self): + """\ + Induce a stop of the running :class:`LoadChecker`' thread. + + When stopped, no more queries to remote X2Go Servers will be + made. + + """ self.keep_alive = False -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit 9f9e5d63d17ae5248f182e2626fcd6105753d4f5 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Thu Sep 13 09:46:50 2018 +0200 x2gobroker/utils.py: Provide/improve API documentation for our utility functions. --- x2gobroker/utils.py | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/x2gobroker/utils.py b/x2gobroker/utils.py index 1811ebb..8f703db 100644 --- a/x2gobroker/utils.py +++ b/x2gobroker/utils.py @@ -17,6 +17,16 @@ # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +"""\ +Here you find a collection of tools that are used by X2Go Session +Broker's code internally. + +Everything that is not directly related to specific broker code and +potentially reusable at other places in the code tree, is placed into +this module. + +""" + import os import sys import locale @@ -95,6 +105,9 @@ def compare_versions(version_a, op, version_b): :param version_b: another version string that is to be compared with <version_a> :type version_b: ``str`` + :returns: if the comparison is ``True`` or ``False`` + :rtype: ``bool`` + """ ### FIXME: this comparison is not reliable with beta et al. version strings @@ -107,6 +120,29 @@ def compare_versions(version_a, op, version_b): def normalize_hostnames(servers): """\ + Take a ``list`` or ``dict`` of servers and check if they match in + their domain part and strip the domain part finally off. + + E.g., for servers provided as a ``list`` (tuple would be ok, too:: + + ['server1', 'server2'] -> ['server1', server2'] + ['server1.domain1, 'server2.domain1'] -> ['server1', server2'] + ['server1.domain1, 'server2.domain2'] -> (['server1', server2'], ['domain1', 'domain2'] + + E.g., for servers provided as a ``dict``:: + + {'server1': <whatever-params>, 'server2': <whatever-params> } -> {'server1': <whatever-params>, 'server2': <whatever-params> } + + {'server1.domain1': <whatever-params>, 'server2.domain1': <whatever-params> } -> {'server1': <whatever-params>, 'server2': <whatever-params> } + + {'server1.domain1': <whatever-params>, 'server2.domain2': <whatever-params> } -> ({'server1': <whatever-params>, 'server2': <whatever-params> }, ['domain1', 'domain2'] + + :param servers: a ``list``, ``tuple`` or ``dict`` hash with either server hostnames as items or dictionary keys + :type servers: ``list``, ``tuple`` or ``dict`` + + :returns: a ``list`` or a ``dict`` with server domains stripped of the items / keys + :rtype: ``list``, ``dict`` or ``tuple`` + """ # test the data type of servers @@ -147,7 +183,22 @@ def normalize_hostnames(servers): return servers_normalized, subdomains def matching_hostnames(server_list_a, server_list_b): + """\ + Compare two list of servers, if they have matching hostnames. + + This function tries to smoothly ship around asymmetric usage of + FQDN hostnames and short hostnames in one list. + + :param server_list_a: list of servers + :type server_list_a: ``list`` of ``str`` + :param server_list_b: list of servers to compare the first list with + :type server_list_b: ``list`` of ``str`` + :returns: a sorted list of matching server hostnames (hostnames that + appear in both provided server lists. + :returns: ``list`` of ``str`` + + """ matching_hosts = [] ### NORMALIZE (=reduce to hostname only) server names (list A) if possible @@ -169,6 +220,24 @@ def matching_hostnames(server_list_a, server_list_b): return matching_hosts def drop_privileges(uid, gid): + """\ + Drop privileges from super-user root to given ``<uid>`` and ``<gid>``. + + Only works when run as root, if run with a non-super-user account, + ``None`` is returned. + + If privileges could be dropped, the environment's HOME variable is + adapted to the new user account's home directory path. + + Also, the umask of the account we dropped privileges to is set to + ``0o077``. + + :param uid: the user ID of the user account to drop privileges to + :type uid: ``str`` + :param gid: the group ID to drop privileges to + :type gid: ``str`` + + """ if os.getuid() != 0: # We're not root so, like, whatever dude return @@ -191,7 +260,28 @@ def drop_privileges(uid, gid): os.environ['HOME'] = pwd.getpwnam(uid).pw_dir def split_host_address(host, default_address=None, default_port=22): + """\ + Try to split a ``<host_addr>:<port>`` expression into hostname and port. + + This function is supposed to work with DNS hostnames, IPv4 and IPv6 + address. + + Both parts (<host_addr> and <port>) can be omitted in the given + ``host`` string. If so, ``default_address`` and ``default_port`` come + into play. + + :param host: an expression like ``<host_addr>:<port>`` (where either + the host address or the port can be optional) + :type host: ``str`` + :param default_address: a fallback host address to be used (default: None) + :type default_address: ``str`` + :param default_port: a fallback port to be used (default: 22) + :type default_port: ``int`` + :returns: a tuple of host address and port + :rtype: ``tuple(<host_addr>, <port>)`` + + """ if type(host) is int: host = str(host) # do some stripping first... @@ -244,7 +334,7 @@ def split_host_address(host, default_address=None, default_port=22): def portscan(addr, port=22): """\ - Performing a port scan to the requested hostname. + Perform a port scan to the requested hostname. :param addr: address (IPv4, IPv6 or hostname) of the host we want to probe @@ -252,6 +342,9 @@ def portscan(addr, port=22): :param port: port number (default: 22) :type port: ``int`` + :returns: ``True`` if the port is in use, else ``False`` (also on errors) + :rtype: ``bool`` + """ ip_proto = 0 try: @@ -289,6 +382,8 @@ def get_key_fingerprint(key): """\ Retrieve the host key fingerprint of the server to be validated. + :param key: a Python Paramik :class:`PKey`` object + :type key: ``PKey`` :returns: host key fingerprint :rtype: ``str`` @@ -300,6 +395,8 @@ def get_key_fingerprint_with_colons(key): Retrieve the (colonized) host key fingerprint of the server to be validated. + :param key: a Python Paramik :class:`PKey`` object + :type key: ``PKey`` :returns: host key fingerprint (with colons) :rtype: ``str`` -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit 87e07e32a640b1e714bae5f3e943847f9a8ccc49 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Thu Sep 13 14:53:32 2018 +0200 x2gobroker/agent.py: Avoid zombie x2gobroker-agent processes by terminating the process and emptying the communication buffers. --- x2gobroker/agent.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x2gobroker/agent.py b/x2gobroker/agent.py index 5aaa115..14620de 100644 --- a/x2gobroker/agent.py +++ b/x2gobroker/agent.py @@ -160,6 +160,8 @@ def _call_local_broker_agent(username, task, cmdline_args=[], logger=None): ) result = agent_process.stdout.read().decode().split('\n') + agent_process.terminate() + agent_process.communicate() except OSError: result = None -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit c3067f00df60d43ebbbecf5dd6f0f8da3c4221e4 Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Thu Sep 13 15:26:01 2018 +0200 bin/x2gobroker: If binding the http server fails, a non-zero exit code should be returned. (Fixes: #1013). --- bin/x2gobroker | 6 +++++- debian/changelog | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/x2gobroker b/bin/x2gobroker index 47649f1..bf3dfa9 100755 --- a/bin/x2gobroker +++ b/bin/x2gobroker @@ -294,7 +294,11 @@ if __name__ == "__main__": else: # run without https http_server = tornado.httpserver.HTTPServer(application) - http_server.listen(bind_port, address=bind_address) + try: + http_server.listen(bind_port, address=bind_address) + except OSError as e: + print (e) + sys.exit(1) if CAN_DAEMONIZE and cmdline_args.daemonize: atexit.register(cleanup_on_exit) diff --git a/debian/changelog b/debian/changelog index fc33189..7217c4f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -75,6 +75,8 @@ x2gobroker (0.0.4.0-0x2go1) UNRELEASED; urgency=medium install into x2gobroker bin:pkg (on DEB based systems). - Makefile.docupload: Add apidoc target (running sphinx-apidoc). - docs/source: Initialize Sphinx API documentation's .rst files. + - bin/x2gobroker: If binding the http server fails, a non-zero exit code + should be returned. (Fixes: #1013). * debian/*: + Trigger Makefile's install target and install those files. Drop debhelper from-source-installation magic. -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git