console_setup.in 3.04 KB
Newer Older
1 2 3 4 5 6
#!/usr/bin/perl -wT
use English;

#
# usage: console_setup node [node node ...]
#
7 8 9 10 11
sub usage()
{
    print STDOUT "Usage: console_setup node [node ...]\n";
    exit(-1);
}
12 13 14 15 16

#
# Configure variables
#
my $TB		= "@prefix@";
17
my $TESTMODE	= @TESTMODE@;
18
my $TBPID	= "@TBADMINGROUP@";
19 20

#
21
# Testbed Support libraries
22
#
23 24 25
use lib "@prefix@/lib";
use libdb;
use libtestbed;
26 27 28

# Turn off line buffering on output
$| = 1; 
29

30
my $SSH		= "$TB/bin/sshtb -n -l root ";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
31
my $PROG	= "/usr/testbed/sbin/console_setup.proxy";
32
my %cmdargs     = ();
33 34 35 36 37 38 39
my @row;

# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

#
40 41 42 43 44
# Parse command arguments. Once we return from getopts, all that should
# left are the required arguments.
#
if (@ARGV == 0) {
    usage();
45
}
46
my @nodes = @ARGV;
47 48 49 50 51 52

#
# 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) {
Leigh B. Stoller's avatar
Leigh B. Stoller committed
53 54
    die("*** $0:\n".
	"    Must be root! Maybe its a development version?\n");
55 56 57 58 59 60 61
}

#
# Build of a list of nodes/pid pairs and then send the command over to
# plastic.
# 
foreach my $node (@nodes) {
62 63
    my($db_result);
    
64 65 66 67 68 69
    #
    # Untaint the argument. 
    #
    if ($node =~ /^([-\@\w.]+)$/) {
	$node = $1;
    }
70 71 72
    else {
	die("Tainted node name: $node");
    }
73 74

    #
75 76 77 78
    # 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.
79
    #
80 81 82 83 84 85
    $tiplines_result =
	DBQueryFatal("select tipname,server from tiplines ".
		     "where node_id='$node'");

    if (! $tiplines_result->numrows) {
	next;
86
    }
87 88 89 90 91 92 93 94 95 96 97 98

    #
    # 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'");

99
    if ($db_result->numrows > 0) {
100 101 102 103 104 105
	@row = $db_result->fetchrow_array();
	$pid = $row[0];
    }
    else {
	$pid = $TBPID;
    }
106 107

    #
108 109 110 111
    # 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.
112
    #
113 114 115 116 117 118 119 120 121 122
    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 ";
	}
123 124 125 126 127
    }
}

if ($TESTMODE) {
    exit 0;
128 129
}

130 131 132
#
# Run the console setup program on the tip server nodes.
# 
133
$UID = 0;
134 135 136
foreach my $server (keys(%cmdargs)) {
    my $args = $cmdargs{$server};

137
    if (system("$SSH -host $server $PROG $args")) {
138 139 140
	print STDERR "*** Failed: $SSH $server $PROG $args: $?\n";
	exit 1;
    }
141
}
142 143

exit 0;