deletenode.in 3.36 KB
Newer Older
1 2 3
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2004, 2005 University of Utah and the Flux Group.
5 6
# All rights reserved.
#
7 8
# deletenode - a script for deleting a node from the database
#
9 10

#
11
# Configure variables
12
#
13 14 15
my $TB         = "@prefix@";
my $ELABINELAB = @ELABINELAB@;
my $KILL       = "/bin/kill";
16 17 18 19

use lib '@prefix@/lib';
use libdb;

20 21
use Getopt::Std;

22 23 24 25 26 27 28 29 30 31 32 33 34
# Turn off line buffering on output
$| = 1;

#
# A list of all the tables we have to delete this node from, and the name of
# the column(s) in that table that contains a node name
#
my %clean_tables = TBDB_PHYSICAL_NODE_TABLES;

if (!TBAdmin()) {
    die "Sorry, only testbed administrators can run this script!\n";
}

35 36 37 38
#
# Handle command-line arguments
#
sub usage {
39
    die "usage: deletenode [-b] [-f] [-q] <node>\n";
40 41 42
}

my %options = ();
43
if (!getopts("bfq",\%options)) {
44 45 46
    usage();
}

47 48
my $node = shift @ARGV;
if (!$node || @ARGV) {
49
    usage();
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
}

#
# Start off with some serious sanity checks
#

#
# First, make sure the node exists, and only let them delete experimental nodes
#
my $result = DBQueryFatal("select role from nodes where node_id='$node'");
if ($result->num_rows() != 1) {
    die "Node $node does not exist!\n";
}
my ($role) = $result->fetch_row();
if ($role ne "testnode") {
    die "Node $node is not a testnode!\n";
}

#
69 70
# Don't let 'em delete a node that is allocated, except to hwdown. Override
# with force option though (for ElabInElab).
71 72 73 74
#
my ($pid, $eid);
my $allocated = NodeidToExp($node,\$pid,\$eid);
if ($allocated && (($pid ne NODEDEAD_PID) || ($eid ne NODEDEAD_EID))) {
75 76 77 78 79 80 81 82
    print "Node is not free or in the " .
	NODEDEAD_PID . "/" . NODEDEAD_EID . "experiment!\n";
    if (defined($options{"f"}) && $ELABINELAB) {
	print "WARNING: Continuing anyway!\n";
    }
    else {
	exit(-1);
    }
83 84 85 86 87
}

#
# Make sure they know what they are getting themselves into
#
88 89 90 91 92 93 94 95 96 97 98 99
# Note: the -b (batch) option is intentionally undocumented, it should only be
# used from other scripts that have already asked for confirmation
#
unless ($options{b}) {
    print "*** WARNING:\n";
    print "This will erase all evidence that $node ever existed in the testbed!\n";
    print "Are you SURE you want to continue? ";
    my $answer = <>;
    if ($answer !~ /^y/i) {
	print "Okay, aborting...\n";
	exit(1);
    }
100 101 102 103 104 105 106
}

#
# Okay, let's clean out them tables
#
while (my ($table, $clist) = each %clean_tables) {
    foreach my $column (@$clist) {
107 108 109
	print "Removing from table $table, column $column\n"
	    if (! defined($options{"q"}));
	
110
	DBQueryFatal("DELETE FROM $table WHERE $column='$node';");
111 112 113
    }
}

114 115 116
#
# Need to run a bunch of stuff to really kill off the node.
#
117 118
print "Regenerating exports file and restarting daemon.\n"
    if (! defined($options{"q"}));
119 120 121
if (system("$TB/sbin/exports_setup")) {
    print STDERR "*** Failed to reset mountpoints.\n";
}
122 123
print "Regenerating named maps and restarting daemon.\n"
    if (! defined($options{"q"}));
124 125 126
if (system("$TB/sbin/named_setup")) {
    print STDERR "*** Failed to reset named maps.\n";
}
127 128
print "Regenerating DHCPD config file and restarting daemon.\n"
    if (! defined($options{"q"}));
129 130 131
if (system("$TB/sbin/dhcpd_makeconf -i -r")) {
    print STDERR "*** Failed to reset DHCPD config file.\n";
}
132 133 134 135 136
print "Hupping stated so that it will reload its tables\n"
    if (! defined($options{"q"}));
if (system("sudo $KILL -HUP `cat /var/run/stated.pid`")) {
    print STDERR "*** Failed to HUP stated.\n";
}
137
exit 0;