Newer
Older
#!/usr/bin/perl -wT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
use English;
use Getopt::Std;
#
# Turn on/off admin mode for nodes and optionally reboot/wait.
#
sub usage()
{
print STDOUT "Usage: node_admin [-h] [-n | -w] <on | off> [node ....]\n";
print STDOUT " node_admin [-h] [-n | -w] -e pid,eid <on | off>\n";
print STDOUT "-h This message\n";
print STDOUT "-n Do not reboot node\n";
print STDOUT "-w Wait for node to come back up if rebooted\n";
print STDOUT "-e Operate on all nodes in an experiment\n";
print STDOUT "-c cmd Run command in MFS and wait for completion\n".
" (-n and -w apply after the command is run).\n";
exit(-1);
}
my $waitmode = 0;
my $reboot = 1;
#
# Configure variables
#
my $TB = "@prefix@";
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
#
# Turn off line buffering on output
#
$| = 1;
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/sbin:/usr/bin:";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
#
#
my $nodereboot = "$TB/bin/node_reboot";
my $osselect = "$TB/bin/os_select";
my @nodes = ();
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{h})) {
usage();
}
if (defined($options{"n"})) {
$reboot = 0;
}
if (defined($options{"w"})) {
$waitmode = 1;
}
if (defined($options{"c"})) {
$runcmd = $options{"c"};
$onoff = "on";
} else {
if (!@ARGV) {
usage();
}
$onoff = shift(@ARGV);
}
if ($onoff ne "on" && $onoff ne "off") {
usage();
}
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
if (defined($options{"e"})) {
#
# Reboot all nodes in an experiment
#
if (@ARGV) {
usage();
}
my $eidmode = $options{"e"};
my $pid;
my $eid;
if ($eidmode =~ /([-\w]*),([-\w]*)/) {
$pid = $1;
$eid = $2;
}
else {
die("*** $0:\n".
" Invalid argument to -e option: $eidmode\n");
}
#
# Verify permission to muck with this experiment. This is to head off
# permission problems early; the nodes are indvidually checked later
# in the library.
#
if ($UID && !TBAdmin($UID) &&
! TBExptAccessCheck($UID, $pid, $eid, TB_EXPT_MODIFY)) {
die("*** $0:\n".
" You not have permission to reboot nodes in $pid/$eid!\n");
}
my $query_result =
DBQueryFatal("select node_id from reserved where ".
"pid='$pid' and eid='$eid'");
if ($query_result->numrows == 0) {
die("*** $0:\n".
" There are no nodes reserved in pid/eid $pid/$eid\n");
}
while (my ($nodeid) = $query_result->fetchrow_array()) {
push(@nodes, $nodeid);
}
}
else {
if (! @ARGV) {
usage();
}
# Untaint the nodes.
foreach my $node ( @ARGV ) {
if ($node =~ /^([-\w]+)$/) {
$node = $1;
}
else {
die("*** Tainted node name: $node\n");
}
if (!TBValidNodeName($node)) {
die("*** $0:\n".
" Node does not exist: $node\n");
}
push(@nodes, $node);
}
#
# Root and admin types can do whatever they want. Normal users
# can only run this on nodes in their own experiments.
#
if ($UID && !TBAdmin($UID)) {
if (! TBNodeAccessCheck($UID, TB_NODEACCESS_LOADIMAGE, @nodes)) {
die("*** $0:\n".
" You are not allowed to put some nodes into admin mode\n");
}
}
}
my @bad;
my %args;
if ($runcmd ne "") {
#
# Reboot into admin more and run the command
#
%args = ();
$args{'name'} = $0;
$args{'command'} = $runcmd;
if (TBAdminMfsRunCmd(\%args, undef, @nodes)) {
die("*** $0:\n".
" Failed to run '$runcmd' on some of @nodes!\n");
#
# Turn admin mode back off and optionally reboot back to the old OS
#
%args = ();
$args{'name'} = $0;
$args{'on'} = 0;
$args{'clearall'} = 0;
if (TBAdminMfsSelect(\%args, \@bad, @nodes)) {
die("*** $0:\n".
" Could not turn admin mode off for @bad!\n");
}
if ($reboot) {
%args = ();
$args{'name'} = $0;
$args{'on'} = 0;
$args{'reboot'} = $reboot;
$args{'wait'} = $waitmode;
if (TBAdminMfsBoot(\%args, \@bad, @nodes)) {
die("*** $0:\n".
" Did not properly reboot @bad after command!\n");
}
}
$args{'name'} = $0;
$args{'on'} = ($onoff eq "on");
$args{'clearall'} = 0;
if (TBAdminMfsSelect(\%args, \@bad, @nodes)) {
die("*** $0:\n".
" Could not turn admin mode $onoff for @bad!\n");
}
if ($reboot) {
%args = ();
$args{'name'} = $0;
$args{'on'} = ($onoff eq "on");
$args{'reboot'} = $reboot;
$args{'wait'} = $waitmode;
if (TBAdminMfsBoot(\%args, \@bad, @nodes)) {
die("*** $0:\n".
}
exit(0);