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

#
12
# Turn on/off admin mode for nodes and optionally reboot/wait.
13 14 15
#
sub usage()
{
16
    print STDOUT "Usage: node_admin [-h] [-n | -w] <on | off> [node ....]\n";
17
    print STDOUT "       node_admin [-h] [-n | -w] -e pid,eid <on | off>\n";
18 19 20 21 22 23
    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";
24 25
    exit(-1);
}
26
my $optlist  = "hnwe:c:";
27 28
my $waitmode = 0;
my $reboot   = 1;
29
my $runcmd   = "";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
30
my $onoff;
31 32 33 34 35 36 37 38 39 40 41 42

#
# Configure variables
#
my $TB		= "@prefix@";

#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
43
use libadminmfs;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
44 45 46
use User;
use Node;
use Experiment;
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

#
# 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";
63
my $osselect    = "$TB/bin/os_select";
64
my @nodes       = ();
65 66 67 68 69

#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
Leigh B. Stoller's avatar
Leigh B. Stoller committed
70
my %options = ();
71 72 73
if (! getopts($optlist, \%options)) {
    usage();
}
74
if (defined($options{h})) {
75 76
    usage();
}
77 78 79 80 81 82
if (defined($options{"n"})) {
    $reboot = 0;
}
if (defined($options{"w"})) {
    $waitmode = 1;
}
83 84 85
if (defined($options{"c"})) {
    $runcmd = $options{"c"};
    $onoff = "on";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
86 87
}
else {
88 89 90 91 92
    if (!@ARGV) {
	usage();
    }
    $onoff  = shift(@ARGV);
}
93 94 95 96 97

if ($onoff ne "on" && $onoff ne "off") {
    usage();
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
98 99 100 101 102 103 104 105 106
#
# Verify user and get his DB uid and other info for later.
#
my $this_user = User->ThisUser();
if (! defined($this_user)) {
    die("*** $0:\n".
	"    You ($UID) do not exist!\n");
}

107 108 109 110 111 112 113
if (defined($options{"e"})) {
    #
    # Reboot all nodes in an experiment
    #
    if (@ARGV) {
	usage();
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
114 115
    my $experiment = Experiment->Lookup($options{"e"});
    if (!defined($experiment)) {
116
	die("*** $0:\n".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
117
	    "    Unknown experiment!\n");
118 119 120 121 122 123 124
    }

    #
    # Verify permission to muck with this experiment. This is to head off
    # permission problems early; the nodes are indvidually checked later
    # in the library.
    #
Leigh B. Stoller's avatar
Leigh B. Stoller committed
125 126
    if ($UID && !$this_user->IsAdmin() &&
	! $experiment->AccessCheck($this_user, TB_EXPT_MODIFY)) {
127
	die("*** $0:\n".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
128
	    "    You not have permission to reboot nodes in $experiment!\n");
129
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
130 131
    @nodes = $experiment->NodeList();
    if (! @nodes) {
132
	die("*** $0:\n".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
133
            "    There are no nodes reserved in $experiment\n");
134
    }
135 136
}
else {
137 138 139
    if (! @ARGV) {
	usage();
    }
140

Leigh B. Stoller's avatar
Leigh B. Stoller committed
141 142 143
    foreach my $n (@ARGV) {
	my $node = Node->Lookup($n);
	if (!defined($node)) {
144
	    die("*** $0:\n".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
145
		"    Node $n does not exist!\n");
146
	}
147 148 149 150
	if (!$node->IsReserved()) {
	    die("*** $0:\n".
		"    Node $n is not reserved; reserve it first!\n");
	}    
Leigh B. Stoller's avatar
Leigh B. Stoller committed
151 152
	if ($UID && !$this_user->IsAdmin() &&
	    ! $node->AccessCheck($this_user, TB_NODEACCESS_LOADIMAGE)) {
153
	    die("*** $0:\n".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
154
		"    You are not allowed to put $node into admin mode!\n");
155
	}
Leigh B. Stoller's avatar
Leigh B. Stoller committed
156
	push(@nodes, $node);
157 158 159
    }
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
160
my @nodeids = map($_->node_id(), @nodes);
161 162 163 164 165 166 167 168 169 170
my @bad;
my %args;

if ($runcmd ne "") {
    #
    # Reboot into admin more and run the command
    #
    %args = ();
    $args{'name'} = $0;
    $args{'command'} = $runcmd;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
171
    if (TBAdminMfsRunCmd(\%args, undef, @nodeids)) {
172
	die("*** $0:\n".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
173
	    "    Failed to run '$runcmd' on some of @nodeids!\n");
174
    }
175

176 177 178 179 180 181 182
    #
    # Turn admin mode back off and optionally reboot back to the old OS
    #
    %args = ();
    $args{'name'} = $0;
    $args{'on'} = 0;
    $args{'clearall'} = 0;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
183
    if (TBAdminMfsSelect(\%args, \@bad, @nodeids)) {
184 185 186
	die("*** $0:\n".
	    "    Could not turn admin mode off for @bad!\n");
    }
187

188 189 190 191 192 193
    if ($reboot) {
	%args = ();
	$args{'name'} = $0;
	$args{'on'} = 0;
	$args{'reboot'} = $reboot;
	$args{'wait'} = $waitmode;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
194
	if (TBAdminMfsBoot(\%args, \@bad, @nodeids)) {
195
	    die("*** $0:\n".
196
		"    Did not properly reboot @bad after command!\n");
197 198
	}
    }
199 200
    exit(0);
}
201

202 203 204
$args{'name'} = $0;
$args{'on'} = ($onoff eq "on");
$args{'clearall'} = 0;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
205
if (TBAdminMfsSelect(\%args, \@bad, @nodeids)) {
206 207 208 209 210 211 212 213 214
    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;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
215
    if (TBAdminMfsBoot(\%args, \@bad, @nodeids)) {
216
	die("*** $0:\n".
217
	    "    Did not properly reboot @bad!\n");
218
    }
219 220
}
exit(0);