#!/usr/bin/perl -wT use English; # # usage: console_setup node [node node ...] # sub usage() { print STDOUT "Usage: console_setup node [node ...]\n"; exit(-1); } # # Configure variables # my $TB = "@prefix@"; my $TESTMODE = @TESTMODE@; my $TBPID = "@TBADMINGROUP@"; # # Testbed Support libraries # use lib "@prefix@/lib"; use libdb; use libtestbed; # Turn off line buffering on output $| = 1; my $SSH = "$TB/bin/sshtb -n -l root "; my $PROG = "/usr/testbed/sbin/console_setup.proxy"; my %cmdargs = (); my @row; # un-taint path $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; # # Parse command arguments. Once we return from getopts, all that should # left are the required arguments. # if (@ARGV == 0) { usage(); } my @nodes = @ARGV; # # Script must be setuid root. We don't worry about who called us or what # nodes are specified since this script always does the right thing. # if ($EUID != 0) { die("*** $0:\n". " Must be root! Maybe its a development version?\n"); } # # Build of a list of nodes/pid pairs and then send the command over to # plastic. # foreach my $node (@nodes) { my($db_result); # # Untaint the argument. # if ($node =~ /^([-\@\w.]+)$/) { $node = $1; } else { die("Tainted node name: $node"); } # # We need to know all of the tiplines associated with this node, # and where they live. There might not be any at all, in which # case we are done. This query could probably be rolled into the # next query, but that would be confusing. # $tiplines_result = DBQueryFatal("select tipname,server from tiplines ". "where node_id='$node'"); if (! $tiplines_result->numrows) { next; } # # Determine the unix group for the node. # $db_result = DBQueryFatal("select g.unix_name from groups as g ". "left join experiments as e ". " on g.pid=e.pid and g.gid=e.gid ". "left join reserved as r ". " on e.pid=r.pid and e.eid=r.eid ". "where r.node_id='$node'"); if ($db_result->numrows > 0) { @row = $db_result->fetchrow_array(); $pid = $row[0]; } else { $pid = $TBPID; } # # For each tipline associated with the node (might be more than one), # we want to issue the proxy command. However, we want to group all # commands for each server together to avoid a zillion ssh calls. So, # use an array of command arguments, indexed by the tip server. # while (@row = $tiplines_result->fetchrow_array()) { my $tipname = $row[0]; my $server = $row[1]; if (defined($cmdargs{$server})) { $cmdargs{$server} = $cmdargs{$server} . " $tipname $pid"; } else { $cmdargs{$server} = "$tipname $pid "; } } } if ($TESTMODE) { exit 0; } # # Run the console setup program on the tip server nodes. # $UID = 0; foreach my $server (keys(%cmdargs)) { my $args = $cmdargs{$server}; if (system("$SSH -host $server $PROG $args")) { print STDERR "*** Failed: $SSH $server $PROG $args: $?\n"; exit 1; } } exit 0;