Skip to content
Snippets Groups Projects
node_admin.in 3.77 KiB
Newer Older
Leigh B. Stoller's avatar
Leigh B. Stoller committed
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
# All rights reserved.
#
# Turn on/off admin mode for nodes and optionally reboot/wait.
    print STDOUT "Usage: node_admin [-h] [-n | -w] <on | off> [node ....]\n";
    print STDOUT "       node_admin [-h] [-n | -w] -p 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";

#
# 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 $ADMINOSID   = TB_OSID_FREEBSD_MFS;

#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
    usage();
}

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

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);
    }
    # 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");
	}
# Switcheroo the osids on the nodes.
    system("$osselect -t $ADMINOSID @nodes") and
	die("*** $0:\n".
	    "    Failed to set temp boot to $ADMINOSID for some nodes!\n");
    system("$osselect -c -t @nodes") and
	die("*** $0:\n".
	    "    Failed to clear temp boot for some nodes!\n");
DBQueryFatal("update nodes set startupcmd='', startstatus='none' ".
	     "where " . join(" or ", map("node_id='$_'", @nodes)));
    my $optarg = ($options{"w"} ? "-w" : "");
	
    if (system("$nodereboot $optarg @nodes")) {
	    "    WARNING: Could not reboot some nodes!\n");