console_setup.in 3.45 KB
Newer Older
1
#!/usr/bin/perl -wT
Leigh Stoller's avatar
Leigh Stoller committed
2 3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
Leigh Stoller's avatar
Leigh Stoller committed
5 6
# All rights reserved.
#
7
use English;
8
use strict;
9 10 11 12

#
# usage: console_setup node [node node ...]
#
13 14 15 16 17
sub usage()
{
    print STDOUT "Usage: console_setup node [node ...]\n";
    exit(-1);
}
18 19 20 21 22

#
# Configure variables
#
my $TB		= "@prefix@";
23
my $TESTMODE	= @TESTMODE@;
24
my $TBPID	= "@TBADMINGROUP@";
25 26

#
27
# Testbed Support libraries
28
#
29 30 31
use lib "@prefix@/lib";
use libdb;
use libtestbed;
32 33 34

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

36
my $SSH		= "$TB/bin/sshtb -n ";
Leigh Stoller's avatar
Leigh Stoller committed
37
my $PROG	= "/usr/testbed/sbin/console_setup.proxy";
38
my %cmdargs     = ();
39 40 41 42 43 44 45
my @row;

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

#
46 47 48 49 50
# Parse command arguments. Once we return from getopts, all that should
# left are the required arguments.
#
if (@ARGV == 0) {
    usage();
51
}
52
my @nodes = @ARGV;
53 54 55 56 57 58

#
# 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 Stoller's avatar
Leigh Stoller committed
59 60
    die("*** $0:\n".
	"    Must be root! Maybe its a development version?\n");
61 62 63 64 65 66 67
}

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

    #
82 83 84 85
    # 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.
86
    #
87 88
    my $tiplines_result =
	DBQueryFatal("select tipname,server,disabled from tiplines ".
89 90
		     "where node_id='$node' and ".
		     "server!='' and keydata is not null");
91 92 93

    if (! $tiplines_result->numrows) {
	next;
94
    }
95 96 97 98 99

    #
    # Determine the unix group for the node. 
    #
    $db_result =
100 101 102 103 104
	DBQueryFatal("select g.unix_name from reserved as r ".
		     "left join experiments as e on ".
		     " r.pid=e.pid and r.eid=e.eid ".
		     "left join groups as g on ".
		     " g.pid=e.pid and g.gid=e.gid ".
105 106
		     "where r.node_id='$node'");

107
    if ($db_result->numrows > 0) {
108 109 110 111 112 113
	@row = $db_result->fetchrow_array();
	$pid = $row[0];
    }
    else {
	$pid = $TBPID;
    }
114 115

    #
116 117 118 119
    # 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.
120
    #
121 122 123
    while (@row = $tiplines_result->fetchrow_array()) {
	my $tipname = $row[0];
	my $server  = $row[1];
124 125 126 127 128 129 130 131 132 133
	my $disabled= $row[2];

	#
	# Let people know that a console line is disabled cause
	# otherwise we will all forgot about it.
	#
	if ($disabled) {
	    print "Skipping disabled tipline: $tipname on $server ...\n";
	    next;
	}
134 135 136 137 138 139 140

	if (defined($cmdargs{$server})) {
	    $cmdargs{$server} = $cmdargs{$server} . " $tipname $pid";
	}
	else {
	    $cmdargs{$server} = "$tipname $pid ";
	}
141 142 143 144 145
    }
}

if ($TESTMODE) {
    exit 0;
146 147
}

148 149 150
#
# Run the console setup program on the tip server nodes.
# 
151
$UID = 0;
152 153 154
foreach my $server (keys(%cmdargs)) {
    my $args = $cmdargs{$server};

155
    if (system("$SSH -host $server $PROG $args")) {
156 157 158
	print STDERR "*** Failed: $SSH $server $PROG $args: $?\n";
	exit 1;
    }
159
}
160 161

exit 0;