[X2Go-Commits] [x2gobroker] 01/01: Provide tool: x2gobroker-testagent.
git-admin at x2go.org
git-admin at x2go.org
Tue Mar 18 19:23:00 CET 2014
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to branch master
in repository x2gobroker.
commit 436b30fe4508905a92baf41a3c98d0e8778f000e
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date: Tue Mar 18 19:23:03 2014 +0100
Provide tool: x2gobroker-testagent.
---
bin/x2gobroker | 22 +-----
debian/changelog | 1 +
debian/rules | 1 +
lib/x2gobroker-agent.pl | 24 +++++++
sbin/x2gobroker-testagent | 142 +++++++++++++++++++++++++++++++++++++
x2gobroker/agent.py | 43 ++++++++++-
x2gobroker/brokers/base_broker.py | 6 +-
x2gobroker/utils.py | 19 +++++
8 files changed, 234 insertions(+), 24 deletions(-)
diff --git a/bin/x2gobroker b/bin/x2gobroker
index b94443c..b1f8258 100755
--- a/bin/x2gobroker
+++ b/bin/x2gobroker
@@ -92,25 +92,7 @@ except ImportError:
from x2gobroker import __VERSION__
from x2gobroker import __AUTHOR__
from x2gobroker.loggers import logger_broker, logger_access, logger_error, tornado_log_request
-
-def drop_privileges(uid=x2gobroker.defaults.X2GOBROKER_DAEMON_USER, gid=x2gobroker.defaults.X2GOBROKER_DAEMON_USER):
- if os.getuid() != 0:
- # We're not root so, like, whatever dude
- return
-
- # Get the uid/gid from the name
- running_uid = pwd.getpwnam(uid).pw_uid
- running_gid = grp.getgrnam(gid).gr_gid
-
- # Remove group privileges
- os.setgroups([])
-
- # Try setting the new uid/gid
- os.setgid(running_gid)
- os.setuid(running_uid)
-
- # Ensure a very conservative umask
- old_umask = os.umask(077)
+from x2gobroker.utils import drop_privileges
interactive_mode_warning = False
# check effective UID the broker runs as and complain appropriately...
@@ -166,7 +148,7 @@ if __name__ == "__main__":
cmdline_args = p.parse_args()
if os.getuid() == 0 and cmdline_args.drop_privileges:
- drop_privileges()
+ drop_privileges(uid=x2gobroker.defaults.X2GOBROKER_DAEMON_USER, gid=x2gobroker.defaults.X2GOBROKER_DAEMON_GROUP)
if cmdline_args.config_file is not None:
x2gobroker.defaults.X2GOBROKER_CONFIG = cmdline_args.config_file
diff --git a/debian/changelog b/debian/changelog
index 69afeed..0ac02f0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -98,6 +98,7 @@ x2gobroker (0.0.3.0-0x2go1) UNRELEASED; urgency=low
- Handle selectsessions calls with a non-existent profile ID gracefully.
- Session profiles with marker user=BROKER_USER will now auto-fill-in the
broker username into the session profile's 'user' option.
+ - Provide tool: x2gobroker-testagent.
* debian/control:
+ Replace LDAP support with session brokerage support in LONG_DESCRIPTION.
+ Fix SYNOPSIS texts.
diff --git a/debian/rules b/debian/rules
index b1eb079..3b69310 100755
--- a/debian/rules
+++ b/debian/rules
@@ -24,6 +24,7 @@
export PREFIX=/usr
include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/makefile.mk
DEB_PYTHON_SYSTEM = $(shell test -f /usr/bin/dh_python2 && echo "" || echo "pysupport")
DEB_PYTHON_INSTALL_ARGS_python-x2gobroker ?= --root=$(DEB_DESTDIR) --prefix=$(DEB_PYTHON_PREFIX_ARG) --no-compile -O0 --install-layout=deb
diff --git a/lib/x2gobroker-agent.pl b/lib/x2gobroker-agent.pl
index abab968..7c04a42 100755
--- a/lib/x2gobroker-agent.pl
+++ b/lib/x2gobroker-agent.pl
@@ -24,6 +24,19 @@ use strict;
use File::Basename;
+my @available_tasks = (
+ "availabletasks",
+ "listsessions",
+ "findbusyservers",
+ "findbusyservers_by_sessionstats",
+ "getservers",
+ "addauthkey",
+ "delauthkey",
+ "suspendsession",
+ "terminatesession",
+);
+
+
sub InitX2GoUser
{
my ($user, $uidNumber, $gidNumber, $home)=@_;
@@ -111,6 +124,17 @@ if($uidNumber < 1000)
die 'operation on system user';
}
+if($mode eq 'availabletasks')
+{
+ InitX2GoUser($uid, $uidNumber, $gidNumber, $home);
+ print "OK\n";
+ my $available_task;
+ foreach $available_task (@available_tasks) {
+ print "$available_task\n";
+ }
+}
+
+
if($mode eq 'listsessions')
{
InitX2GoUser($uid, $uidNumber, $gidNumber, $home);
diff --git a/sbin/x2gobroker-testagent b/sbin/x2gobroker-testagent
new file mode 100755
index 0000000..c22b5a7
--- /dev/null
+++ b/sbin/x2gobroker-testagent
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+
+# This file is part of the X2Go Project - http://www.x2go.org
+# Copyright (C) 2011-2014 by Oleksandr Shneyder <oleksandr.shneyder at obviously-nice.de>
+# Copyright (C) 2011-2014 by Heinz-Markus Graesing <heinz-m.graesing at obviously-nice.de>
+# Copyright (C) 2012-2014 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 os
+import sys
+import setproctitle
+import argparse
+import logging
+
+# perform an authentication against the authentication mechanism configured for WSGI
+try:
+ import x2gobroker.defaults
+except ImportError:
+ sys.path.insert(0, os.path.join(os.getcwd(), '..'))
+ import x2gobroker.defaults
+import x2gobroker.loggers
+
+import x2gobroker.agent
+from x2gobroker.utils import drop_privileges
+
+PROG_NAME = os.path.basename(sys.argv[0])
+PROG_OPTIONS = sys.argv[1:]
+try:
+ _password_index = PROG_OPTIONS.index('--password')+1
+ PROG_OPTIONS[_password_index] = "XXXXXXXX"
+except ValueError:
+ # ignore if --password option is not specified
+ pass
+setproctitle.setproctitle("%s %s" % (PROG_NAME, " ".join(PROG_OPTIONS)))
+
+if __name__ == "__main__":
+
+ agent_options = [
+ {'args':['--drop-privileges'], 'default': False, 'action': 'store_true', 'help': 'Drop privileges to user {x2gobroker} (recommended)'.format(x2gobroker=x2gobroker.defaults.X2GOBROKER_DAEMON_USER), },
+ {'args':['-H','--host'], 'default': 'LOCAL', 'metavar': 'HOSTNAME', 'help': 'Test X2Go Session Broker Agent on this host (default: LOCAL)', },
+ {'args':['-p','--port'], 'default': 22, 'metavar': 'PORT', 'help': 'For remote agent calls (via SSH) use this port as SSH port (default: 22)', },
+ {'args':['-u','--username'], 'default': None, 'metavar': 'USERNAME', 'help': 'When testing the broker agent, test on behalf of this user (default: none)', },
+ {'args':['-t','--task'], 'default': 'PING_ICMP', 'metavar': 'AGENT_TASK', 'help': 'Perform this task on the (remote) broker agent', },
+ {'args':['--list-tasks'], 'default': False, 'action': 'store_true', 'help': 'List available broker agent tasks', },
+ ]
+ misc_options = [
+ {'args':['-C','--config-file'], 'default': None, 'metavar': 'CONFIG_FILE', 'help': 'Specify a special configuration file name, default is: {default}'.format(default=x2gobroker.defaults.X2GOBROKER_CONFIG), },
+ {'args':['-d','--debug'], 'default': False, 'action': 'store_true', 'help': 'enable debugging code', },
+ ]
+ p = argparse.ArgumentParser(description='X2Go Session Broker (Agent Test Utility)',\
+ formatter_class=argparse.RawDescriptionHelpFormatter, \
+ add_help=True, argument_default=None)
+ p_agent = p.add_argument_group('agent parameters')
+ p_misc = p.add_argument_group('miscellaneous parameters')
+
+ for (p_group, opts) in ( (p_agent, agent_options), (p_misc, misc_options), ):
+ for opt in opts:
+ args = opt['args']
+ del opt['args']
+ p_group.add_argument(*args, **opt)
+
+ cmdline_args = p.parse_args()
+
+ if cmdline_args.username is None and not cmdline_args.list_tasks:
+ p.print_help()
+ print
+ print "*** Cannot continue without username... ***"
+ print
+ sys.exit(-1)
+
+ if cmdline_args.config_file is not None:
+ x2gobroker.defaults.X2GOBROKER_CONFIG = cmdline_args.config_file
+
+ if cmdline_args.drop_privileges:
+ drop_privileges(uid=x2gobroker.defaults.X2GOBROKER_DAEMON_USER, gid=x2gobroker.defaults.X2GOBROKER_DAEMON_GROUP)
+
+ if cmdline_args.debug:
+ x2gobroker.defaults.X2GOBROKER_DEBUG = cmdline_args.debug
+ # raise log level to DEBUG if requested...
+ if x2gobroker.defaults.X2GOBROKER_DEBUG and not x2gobroker.defaults.X2GOBROKER_TESTSUITE:
+ x2gobroker.loggers.logger_broker.setLevel(logging.DEBUG)
+ x2gobroker.loggers.logger_error.setLevel(logging.DEBUG)
+
+ username = cmdline_args.username
+ hostname = cmdline_args.host
+ port = cmdline_args.port
+ task = cmdline_args.task
+
+ list_tasks = cmdline_args.list_tasks
+
+local_agent = (hostname == 'LOCAL')
+query_mode = local_agent and 'LOCAL' or 'SSH'
+if local_agent: remote_agent = None
+else: remote_agent = {'hostname': hostname, 'port': port, }
+
+agent_client_tasks = x2gobroker.agent.tasks
+if 'availabletasks' in agent_client_tasks:
+ try:
+ remote_agent_tasks = x2gobroker.agent.tasks_available(username=username, query_mode=query_mode, remote_agent=remote_agent)
+ except x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException, e:
+ print e
+ sys.exit(0)
+
+def call_agent(task):
+ return agent_client_tasks[task](username=username, query_mode=query_mode, remote_agent=remote_agent)
+
+if __name__ == "__main__":
+
+ if not local_agent and not x2gobroker.agent.has_remote_broker_agent_setup():
+
+ print "This instance of X2Go Session Broker is not able to contact any remote"
+ print "X2Go Session Broker Agent instances. Check this broker's SSH setup!!!"
+ print
+ print "Aborting any futher tests..."
+ sys.exit(-1)
+
+ if list_tasks:
+ print "The queried broker agent supports these tasks / features:"
+ print
+ for task in remote_agent_tasks:
+ try:
+ print " {task_name}: {task_function_obj}".format(task_name=task, task_function_obj=agent_client_tasks[task])
+ except KeyError:
+ print " {task_name}: not supported by this broker version".format(task_name=task)
+ print
+ sys.exit(0)
+
+ call_agent(task)
diff --git a/x2gobroker/agent.py b/x2gobroker/agent.py
index 183985f..7d0baca 100644
--- a/x2gobroker/agent.py
+++ b/x2gobroker/agent.py
@@ -35,6 +35,8 @@ import x2gobroker.defaults
import x2gobroker.x2gobroker_exceptions
from x2gobroker.loggers import logger_broker, logger_error
+tasks = {}
+
class delayed_execution(threading.Thread):
@@ -54,7 +56,6 @@ class delayed_execution(threading.Thread):
self.agent_func(**self.kwargs)
-
def has_remote_broker_agent_setup():
"""\
Peform some integrity checks that may indicate that a remote
@@ -72,6 +73,7 @@ def has_remote_broker_agent_setup():
elif os.path.exists(os.path.join(home, '.ssh', 'id_ecdsa')):
return True
+
def call_local_broker_agent(username, mode, cmdline_args=[]):
"""\
Launch X2Go Broker Agent locally and process its output.
@@ -110,6 +112,7 @@ def call_local_broker_agent(username, mode, cmdline_args=[]):
raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Query to local X2Go Broker Agent failed with no response')
+
def call_remote_broker_agent(username, mode, cmdline_args=[], remote_agent=None):
"""\
Launch remote X2Go Broker Agent via SSH and process its output.
@@ -162,7 +165,9 @@ def call_remote_broker_agent(username, mode, cmdline_args=[], remote_agent=None)
client.close()
if result and result[0].startswith('OK'):
return [ r for r in result[1:] if r ]
- except (paramiko.SSHException, paramiko.AuthenticationException, paramiko.BadHostKeyException, socket.error):
+ except paramiko.AuthenticationException:
+ raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Authentication to remote X2Go Broker Agent Host failed (user: {user}, hostname: {hostname}, port: {port}) failed'.format(user=remote_username, hostname=remote_hostname, port=remote_port))
+ except (paramiko.SSHException, paramiko.BadHostKeyException, socket.error):
raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Query to remote X2Go Broker Agent (user: {user}, hostname: {hostname}, port: {port}) failed'.format(user=remote_username, hostname=remote_hostname, port=remote_port))
@@ -212,6 +217,7 @@ def ping(query_mode='LOCAL', remote_agent=None):
return remote_agent is not None and \
icmp_ping(remote_agent['hostname']) and \
call_remote_broker_agent(username, mode='ping', remote_agent=remote_agent)
+tasks['ping'] = ping
def list_sessions(username, query_mode='LOCAL', remote_agent=None):
@@ -230,6 +236,7 @@ def list_sessions(username, query_mode='LOCAL', remote_agent=None):
return call_local_broker_agent(username, mode='listsessions')
else:
return call_remote_broker_agent(username, mode='listsessions', remote_agent=remote_agent)
+tasks['listsessions'] = list_sessions
def suspend_session(username, session_name, query_mode='LOCAL', remote_agent=None):
@@ -248,6 +255,7 @@ def suspend_session(username, session_name, query_mode='LOCAL', remote_agent=Non
return call_local_broker_agent(username, mode='suspendsession', cmdline_args=[session_name, ], )
else:
return call_remote_broker_agent(username, mode='suspendsession', cmdline_args=[session_name, ], remote_agent=remote_agent)
+tasks['suspendsession'] = suspend_session
def terminate_session(username, session_name, query_mode='LOCAL', remote_agent=None):
@@ -266,6 +274,7 @@ def terminate_session(username, session_name, query_mode='LOCAL', remote_agent=N
return call_local_broker_agent(username, mode='terminatesession', cmdline_args=[session_name, ], )
else:
return call_remote_broker_agent(username, mode='terminatesession', cmdline_args=[session_name, ], remote_agent=remote_agent)
+tasks['terminatesession'] = terminate_session
def has_sessions(username, query_mode='LOCAL', remote_agent=None):
@@ -287,6 +296,7 @@ def has_sessions(username, query_mode='LOCAL', remote_agent=None):
_session_list = list_sessions(username, query_mode=query_mode, remote_agent=remote_agent)
return ([ s.split('|')[3] for s in _session_list if s.split('|')[4] == 'R' ], [ s.split('|')[3] for s in _session_list if s.split('|')[4] == 'S' ])
+
def find_busy_servers(username, query_mode='LOCAL', remote_agent=None):
"""\
Query X2Go Broker Agent for a list of servers with running
@@ -317,6 +327,7 @@ def find_busy_servers(username, query_mode='LOCAL', remote_agent=None):
server_usage.update({ server: int(usage) })
return server_usage
+tasks['findbusyservers'] = find_busy_servers
def add_authorized_key(username, pubkey_hash, authorized_keys_file='%h/.x2go/authorized_keys', query_mode='LOCAL', remote_agent=None):
@@ -339,6 +350,7 @@ def add_authorized_key(username, pubkey_hash, authorized_keys_file='%h/.x2go/aut
return call_local_broker_agent(username, mode='addauthkey', cmdline_args=[pubkey_hash, authorized_keys_file, ])
else:
return call_remote_broker_agent(username, mode='addauthkey', cmdline_args=[pubkey_hash, authorized_keys_file, ], remote_agent=remote_agent)
+tasks['addauthkey'] = add_authorized_key
def delete_authorized_key(username, pubkey_hash, authorized_keys_file='%h/.x2go/authorized_keys', query_mode='LOCAL', remote_agent=None, delay_deletion=0):
@@ -371,6 +383,7 @@ def delete_authorized_key(username, pubkey_hash, authorized_keys_file='%h/.x2go/
return call_local_broker_agent(username, mode='delauthkey', cmdline_args=[pubkey_hash, authorized_keys_file, ])
else:
return call_remote_broker_agent(username, mode='delauthkey', cmdline_args=[pubkey_hash, authorized_keys_file, ], remote_agent=remote_agent)
+tasks['delauthkey'] = delete_authorized_key
def get_servers(username, query_mode='LOCAL', remote_agent=None):
@@ -390,7 +403,30 @@ def get_servers(username, query_mode='LOCAL', remote_agent=None):
if unicode(query_mode).upper() == u'LOCAL':
return call_local_broker_agent(username, mode='getservers')
else:
- return call_local_broker_agent(username, mode='getservers', remote_agent=remote_agent)
+ return call_remote_broker_agent(username, mode='getservers', remote_agent=remote_agent)
+tasks['getservers'] = get_servers
+
+
+def tasks_available(username, query_mode='LOCAL', remote_agent=None):
+ """\
+ Query X2Go Broker Agent for the list of available tasks.
+
+ Depending on the remove broker agent's version, the result of this
+ query can vary tremendously from X2Go Server to X2Go Server.
+
+ @param username: run the query on behalf of this username
+ @type username: C{unicode}
+ @param query_mode: query mode used when calling X2Go Broker Agent (C{LOCAL} or C{SSH})
+ @type query_mode: C{unicode}
+ @param remote_agent: information about the remote agent that is to be called.
+ @type remote_agent: C{dict}
+
+ """
+ if unicode(query_mode).upper() == u'LOCAL':
+ return call_local_broker_agent(username, mode='availabletasks')
+ else:
+ return call_remote_broker_agent(username, mode='availabletasks', remote_agent=remote_agent)
+tasks['availabletasks'] = tasks_available
def genkeypair(local_username, client_address, key_type='RSA'):
@@ -433,3 +469,4 @@ def genkeypair(local_username, client_address, key_type='RSA'):
privkey = privkey_obj.getvalue()
return (pubkey, privkey)
+
diff --git a/x2gobroker/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py
index ad49ef7..0edb946 100644
--- a/x2gobroker/brokers/base_broker.py
+++ b/x2gobroker/brokers/base_broker.py
@@ -1044,7 +1044,11 @@ class X2GoBroker(object):
# find already running/suspended sessions and resume the first one found
if remote_agent and server_list and username:
- session_list = x2gobroker.agent.list_sessions(username=username, query_mode=agent_query_mode, remote_agent=remote_agent)
+ try:
+ session_list = x2gobroker.agent.list_sessions(username=username, query_mode=agent_query_mode, remote_agent=remote_agent)
+ except x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException:
+ session_list = []
+
if session_list:
# if resuming, always select the first session in the list, there should only be one suspended session
diff --git a/x2gobroker/utils.py b/x2gobroker/utils.py
index 34117d5..776f380 100644
--- a/x2gobroker/utils.py
+++ b/x2gobroker/utils.py
@@ -169,3 +169,22 @@ def matching_hostnames(server_list_a, server_list_b):
matching_hosts = list(set(server_list_a).intersection(set(server_list_b)))
return matching_hosts
+
+def drop_privileges(uid, gid):
+ if os.getuid() != 0:
+ # We're not root so, like, whatever dude
+ return
+
+ # Get the uid/gid from the name
+ running_uid = pwd.getpwnam(uid).pw_uid
+ running_gid = grp.getgrnam(gid).gr_gid
+
+ # Remove group privileges
+ os.setgroups([])
+
+ # Try setting the new uid/gid
+ os.setgid(running_gid)
+ os.setuid(running_uid)
+
+ # Ensure a very conservative umask
+ old_umask = os.umask(077)
\ No newline at end of file
--
Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git
More information about the x2go-commits
mailing list