This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gobroker. commit d2bcb528625d029129e537cb8358e6797225814d Author: Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Date: Wed Mar 19 10:01:49 2014 +0100 more work on the x2gobroker-testagent tool --- lib/x2gobroker-agent.pl | 19 ++++++++-- sbin/x2gobroker-testagent | 89 ++++++++++++++++++++++++++++++++++++++++----- x2gobroker/agent.py | 22 +++++++---- 3 files changed, 109 insertions(+), 21 deletions(-) diff --git a/lib/x2gobroker-agent.pl b/lib/x2gobroker-agent.pl index 02a4b33..ccb8ebb 100755 --- a/lib/x2gobroker-agent.pl +++ b/lib/x2gobroker-agent.pl @@ -82,10 +82,15 @@ sub AddAuthKey # make sure dir and file for authorized_keys do exist system ("sudo", "-u", "$uid", "--", "mkdir", "-p", "$authkeydir"); system ("sudo", "-u", "$uid", "--", "touch", "$authkeyfile"); - my $authorized_keys = `sudo -u $uid -- "cat $authkeyfile"`; + my $authorized_keys = `sudo -u $uid -- cat "$authkeyfile"`; if ( ! ( $authorized_keys =~ m/$pubkey/ ) ) { - system("sudo", "-u", "$uid", "--", "echo $pubkey >> $authkeyfile"); + open my $saveout, ">&STDOUT"; + open STDOUT, '>', "/dev/null"; + open(TEE_STDIN, "| sudo -u $uid -- tee -a $authkeyfile"); + print TEE_STDIN "$pubkey\n"; + close(TEE_STDIN); + open STDOUT, ">&", $saveout; } } @@ -101,7 +106,13 @@ sub DelAuthKey { $authkeyfile = "$home/$authkeyfile"; } - system("sudo", "-u", "$uid", "--", "sed -e s\!'$pubkey'\!''\! -e '/^\$/d' -i $authkeyfile 1>/dev/null 2>/dev/null"); + open my $saveout, ">&STDOUT"; + open STDOUT, '>', "/dev/null"; + open my $saveerr, ">&STDERR"; + open STDERR, '>', "/dev/null"; + system("sudo", "-u", "$uid", "--", "sed", "-e", "s!$pubkey!!", "-e", "/^\$/d", "-i", "$authkeyfile"); + open STDOUT, ">&", $saveout; + open STDERR, ">&", $saveerr; } $< = $>; @@ -164,7 +175,7 @@ if( ($mode eq 'findbusyservers_by_sessionstats') || ($mode eq 'findbusyservers') InitX2GoUser($uid, $uidNumber, $gidNumber, $home); print "OK\n"; - my $busy_servers = `sudo -u $uid -c \"x2gogetservers\"`; + my $busy_servers = `sudo -u $uid -- x2gogetservers`; my %server_load = (); my $num_sessions = 0; diff --git a/sbin/x2gobroker-testagent b/sbin/x2gobroker-testagent index e09c81f..ade4403 100755 --- a/sbin/x2gobroker-testagent +++ b/sbin/x2gobroker-testagent @@ -22,6 +22,7 @@ import os import sys +import types import setproctitle import argparse import logging @@ -52,10 +53,14 @@ if __name__ == "__main__": agent_options = [ {'args':['--list-tasks'], 'default': False, 'action': 'store_true', 'help': 'List available broker agent tasks', }, {'args':['-u','--username', '--user'], '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':['-t','--task'], 'default': 'ping', 'metavar': 'AGENT_TASK', 'help': 'Perform this task on the (remote) broker agent', }, {'args':['-H','--host'], 'default': 'LOCAL', 'metavar': 'HOSTNAME', 'help': 'Test X2Go Session Broker Agent on this (remote) 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)', }, ] + supplementary_options = [ + {'args':['--session-id'], 'default': None, 'help': 'when testing the \'suspendsession\' or the \'terminatesession\' task, you have to additionally give a session ID to test the tasks on', }, + {'args':['--pubkey'], 'default': None, 'help': 'use this public key when testing the \'addauthkey\' and the \'delauthkey\' task', }, + ] 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', }, @@ -64,9 +69,10 @@ if __name__ == "__main__": formatter_class=argparse.RawDescriptionHelpFormatter, \ add_help=True, argument_default=None) p_agent = p.add_argument_group('agent parameters') + p_supplimentary = p.add_argument_group('supplimentary parameters') p_misc = p.add_argument_group('miscellaneous parameters') - for (p_group, opts) in ( (p_agent, agent_options), (p_misc, misc_options), ): + for (p_group, opts) in ( (p_agent, agent_options), (p_supplimentary, supplementary_options), (p_misc, misc_options), ): for opt in opts: args = opt['args'] del opt['args'] @@ -88,6 +94,13 @@ if __name__ == "__main__": print sys.exit(-1) + if cmdline_args.task in ('suspendsession', 'terminatesession') and not cmdline_args.session_id: + p.print_help() + print + print "*** Cannot continue on this task without a given session ID... ***" + print + sys.exit(0); + if cmdline_args.config_file is not None: x2gobroker.defaults.X2GOBROKER_CONFIG = cmdline_args.config_file @@ -112,10 +125,23 @@ if local_agent: remote_agent = None else: remote_agent = {'hostname': hostname, 'port': port, } def call_agent(task, **kwargs): - return agent_client_tasks[task](username=username, query_mode=query_mode, remote_agent=remote_agent, **kwargs) + try: + _result = agent_client_tasks[task](username=username, query_mode=query_mode, remote_agent=remote_agent, **kwargs) + if _result == True: + print "The broker agent could be reached but the task returned no printable output (which probably is fine)." + print + return _result + except KeyError: + print "No such task: '{task_name}'. Use --list-tasks to view information about".format(task_name=task) + print "available tasks." + print + return False if __name__ == "__main__": + # drop root privileges and run as X2GOBROKER_DAEMON_USER + drop_privileges(uid=x2gobroker.defaults.X2GOBROKER_DAEMON_USER, gid=x2gobroker.defaults.X2GOBROKER_DAEMON_GROUP) + print print "X2Go Session Broker (Agent Test Utility)" print "----------------------------------------" @@ -125,13 +151,10 @@ if __name__ == "__main__": 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 + print "{errmsg}.".format(errmsg=e) print sys.exit(0) - # drop root privileges and run as X2GOBROKER_DAEMON_USER - drop_privileges(uid=x2gobroker.defaults.X2GOBROKER_DAEMON_USER, gid=x2gobroker.defaults.X2GOBROKER_DAEMON_GROUP) - 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" @@ -152,10 +175,58 @@ if __name__ == "__main__": sys.exit(0); kwargs = {} - if task == 'addauthkey': + pubkey = cmdline_args.pubkey + if (task == 'addauthkey' or task == 'delauthkey') and not pubkey: pubkey, privvkey = x2gobroker.agent.genkeypair(local_username=username, client_address="localhost") + + if pubkey: kwargs.update({ 'pubkey_hash': pubkey, }) - print "\n".join(call_agent(task, **kwargs)) + if task in ('suspendsession', 'terminatesession'): + kwargs.update({ + 'session_name': cmdline_args.session_id + }) + + result = call_agent(task, **kwargs) + if type(result) is types.ListType: + print "\n".join(result) + print + elif task.startswith('findbusyservers') and type(result) is types.DictType: + if result: + print "\n".join(result.items()) + else: + print "X2Go Server busy state: All servers are idle." + print + # even an empty dict means, that we have been successful... + result = True + + if task == 'addauthkey' and result: + on_host = " on {host}".format(host=cmdline_args.host) if cmdline_args.host != 'LOCAL' else "" + print "NOTE: This test-run added the below SSH public key to X2Go's authorized_keys file" + print " for user '{username}{on_host}'.".format(username=username, on_host=on_host) + print + print " The file location for this normally is $HOME/.x2go/authorized_keys." + print " MAKE SURE TO REMOVE THIS KEY MANUALLY (or use test the 'delauthkey' task)!!!" + print + print pubkey + print + + if task == 'delauthkey' and result: + on_host = " on {host}".format(host=cmdline_args.host) if cmdline_args.host != 'LOCAL' else "" + print "NOTE: This test-run attempted to remove all occurences of the below SSH public key from" + print " X2Go's authorized_keys file for user '{username}{on_host}'.".format(username=username, on_host=on_host) + print + print " The file location for this normally is $HOME/.x2go/authorized_keys." + print " PLEASE DOUBLE-CHECK THE USER'S authorized_keys file MANUALLY!!!" + print + print pubkey + print + + where = "local" if query_mode == "LOCAL" else "remote" + if result: + print "The task '{task_name}' could be executed successfully on the {where} broker agent.".format(task_name=task, where=where) + else: + print "The task '{task_name}' failed to execute on the {where} broker agent.".format(task_name=task, where=where) + print diff --git a/x2gobroker/agent.py b/x2gobroker/agent.py index 0840023..f8eed07 100644 --- a/x2gobroker/agent.py +++ b/x2gobroker/agent.py @@ -20,6 +20,7 @@ # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. import os.path +import types import subprocess import paramiko import cStringIO @@ -91,7 +92,7 @@ def call_local_broker_agent(username, mode, cmdline_args=[]): ] for cmdline_arg in cmdline_args: - cmd_line.append('\'{arg}\''.format(arg=cmdline_arg)) + cmd_line.append('{arg}'.format(arg=cmdline_arg)) logger_broker.info('Executing agent command locally: {cmd}'.format(cmd=" ".join(cmd_line))) result = ['FAILED'] @@ -108,7 +109,7 @@ def call_local_broker_agent(username, mode, cmdline_args=[]): pass if result[0].startswith('OK'): - return [ r for r in result[1:] if r ] + return [ r for r in result[1:] if r ] or True raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Query to local X2Go Broker Agent failed with no response') @@ -135,7 +136,7 @@ def call_remote_broker_agent(username, mode, cmdline_args=[], remote_agent=None) ] for cmdline_arg in cmdline_args: - cmd_line.append('\'{arg}\''.format(arg=cmdline_arg)) + cmd_line.append('{arg}'.format(arg=cmdline_arg)) remote_username = x2gobroker.defaults.X2GOBROKER_AGENT_USER remote_hostname = remote_agent[u'hostname'] @@ -164,12 +165,15 @@ def call_remote_broker_agent(username, mode, cmdline_args=[], remote_agent=None) logger_broker.warning('Remote agent command (host: {remote_agent}) reported an error: {err}'.format(remote_agent=remote_agent['hostname'], err=err)) client.close() if result and result[0].startswith('OK'): - return [ r for r in result[1:] if r ] + return [ r for r in result[1:] if r ] or True + else: + return False 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)) + raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Query to remote X2Go Broker Agent failed with no response') def icmp_ping(hostname): """\ @@ -321,10 +325,12 @@ def find_busy_servers(username, query_mode='LOCAL', remote_agent=None, **kwargs) server_usage = {} if server_list: - for server_item in server_list: - if ':' in server_item: - usage, server = server_item.split(':') - server_usage.update({ server: int(usage) }) + if type(server_list) is types.ListType: + for server_item in server_list: + print server_item + if ':' in server_item: + usage, server = server_item.split(':') + server_usage.update({ server: int(usage) }) return server_usage tasks['findbusyservers'] = find_busy_servers -- Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git