Commit 4c11aa5d authored by Robert Ricci's avatar Robert Ricci

Lib-ification. These scripts have been changed from using the Mysql module to

using the libdb library. They have also been cleaned up somewhat, with more
comments added, etc.

I've merged nodeip and mac2if, which had very similar functions. The merged
version goes under the name nodeip.

Lastly, I've added some access checks to db2ns and node_status, to make sure
they're only called by the right people.
parent 1325fcc3
...@@ -1024,7 +1024,7 @@ outfiles="$outfiles Makeconf GNUmakefile \ ...@@ -1024,7 +1024,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
db/GNUmakefile db/nalloc db/nfree db/if2port db/backup \ db/GNUmakefile db/nalloc db/nfree db/if2port db/backup \
db/webcontrol db/node_status db/genelists db/genelists.proxy \ db/webcontrol db/node_status db/genelists db/genelists.proxy \
discvr/GNUmakefile \ discvr/GNUmakefile \
db/libdb.pm db/inuse db/avail db/mac2if db/nodeip db/showgraph \ db/libdb.pm db/inuse db/avail db/nodeip db/showgraph \
db/dhcpd_makeconf \ db/dhcpd_makeconf \
ipod/GNUmakefile \ ipod/GNUmakefile \
lib/GNUmakefile \ lib/GNUmakefile \
......
...@@ -146,7 +146,7 @@ outfiles="$outfiles Makeconf GNUmakefile \ ...@@ -146,7 +146,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
db/GNUmakefile db/nalloc db/nfree db/if2port db/backup \ db/GNUmakefile db/nalloc db/nfree db/if2port db/backup \
db/webcontrol db/node_status db/genelists db/genelists.proxy \ db/webcontrol db/node_status db/genelists db/genelists.proxy \
discvr/GNUmakefile \ discvr/GNUmakefile \
db/libdb.pm db/inuse db/avail db/mac2if db/nodeip db/showgraph \ db/libdb.pm db/inuse db/avail db/nodeip db/showgraph \
db/dhcpd_makeconf \ db/dhcpd_makeconf \
ipod/GNUmakefile \ ipod/GNUmakefile \
lib/GNUmakefile \ lib/GNUmakefile \
......
...@@ -8,7 +8,7 @@ SUBDIR = db ...@@ -8,7 +8,7 @@ SUBDIR = db
include $(OBJDIR)/Makeconf include $(OBJDIR)/Makeconf
BIN_SCRIPTS = mac2if nalloc nfree nodeip BIN_SCRIPTS = nalloc nfree nodeip
SBIN_SCRIPTS = avail inuse showgraph if2port backup webcontrol node_status \ SBIN_SCRIPTS = avail inuse showgraph if2port backup webcontrol node_status \
genelists genelists.proxy dhcpd_makeconf genelists genelists.proxy dhcpd_makeconf
LIBEXEC_SCRIPTS = LIBEXEC_SCRIPTS =
......
#!/usr/bin/perl -w #!/usr/bin/perl -w
use Mysql;
use Getopt::Long; use Getopt::Long;
#
# dhcpd_makeconf - helper script to create dhcpd.conf files from the database.
# The template file should look like an ordinary dhcpd.conf file, but have
# the string %%nodetype=<type> where you want entries for a set of nodes
# filled out. For example:
#
# subnet 155.101.132.0 netmask 255.255.252.0 {
# option routers 155.101.132.1;
# option domain-name-servers 155.101.128.70;
# option subnet-mask 255.255.252.0;
#
# option dhcp-class-identifier "PXEClient";
#
# # testbed PCs
# group {
# option dhcp-class-identifier "PXEClient";
#
# %%nodetype=pc600
#
# %%nodetype=pc850
#
# }
# }
# #
# Configure variables # Configure variables
# #
my $DBNAME = "@TBDBNAME@"; use lib "@prefix@/lib";
use libdb;
my %opt = (); my %opt = ();
GetOptions(\%opt,"h","v"); GetOptions(\%opt,"h","v");
if ($opt{h}) { exit &usage; } if ($opt{h}) { exit &usage; }
my $dbh = Mysql->connect("localhost",$DBNAME,"script","none");
$infile = shift @ARGV; # || exit &usage; $infile = shift @ARGV; # || exit &usage;
open(IF,"<$infile") or die "Unable to open $infile for reading\n"; open(IF,"<$infile") or die "Unable to open $infile for reading\n";
...@@ -24,15 +47,17 @@ while (<IF>) { ...@@ -24,15 +47,17 @@ while (<IF>) {
if ($opt{v}) { if ($opt{v}) {
$query .= ", r.vname "; $query .= ", r.vname ";
} }
$query .= "FROM nodes AS n LEFT JOIN interfaces AS i ON n.node_id = i.node_id "; $query .= "FROM nodes AS n LEFT JOIN interfaces AS i ON ".
$query .= "LEFT JOIN node_types AS t ON n.type = t.type "; " n.node_id = i.node_id LEFT JOIN node_types AS t " .
" ON n.type = t.type ";
if ($opt{v}) { if ($opt{v}) {
$query .= "LEFT JOIN reserved AS r ON n.node_id = r.node_id "; $query .= "LEFT JOIN reserved AS r ON n.node_id = r.node_id ";
} }
$query .= "WHERE n.type='$nodetype' AND i.card = t.control_net "; $query .= "WHERE n.type='$nodetype' AND i.card = t.control_net ";
$query .= "ORDER BY n.priority"; $query .= "ORDER BY n.priority";
my $sth = $dbh->query($query);
while (@row = $sth->fetchrow) { my $result = DBQueryFatal($query);
while (@row = $result->fetchrow) {
my $ip = $row[1]; my $ip = $row[1];
my $mac = $row[2]; my $mac = $row[2];
my $node_id; my $node_id;
......
#!/usr/local/bin/perl -w #!/usr/local/bin/perl -w
use Mysql;
use Getopt::Std; use Getopt::Std;
use strict; use strict;
use lib "@prefix@/lib";
use libdb;
#
# if2port - Given an interface (specified as node[:card]), find the
# port on the switches that it's connected to. With the -v switch, gives
# some human-readable information to help in following wires and diagnosing
# problems.
#
#
# IMPORTANT: This file contains some information specific to the Utah # IMPORTANT: This file contains some information specific to the Utah
# Network Testbed! If you want to use it in another enviroment, change # Network Testbed! If you want to use it in another enviroment, change
# the information below # the information below (%switches, %cards, %wires)
#
# Describes the location of each of the switches that nodes may be connected # Describes the location of each of the switches that nodes may be connected
# to # to
#
my %switches = ( cisco1 => 'top right', cisco2 => 'bottom right', my %switches = ( cisco1 => 'top right', cisco2 => 'bottom right',
cisco3 => 'top left', cisco4 => 'bottom left'); cisco3 => 'top left', cisco4 => 'bottom left');
#
# Description of the location of each chard on the back of a machine. # Description of the location of each chard on the back of a machine.
# A hash, indexed by node type. Each value is an array reference, ordered # A hash, indexed by node type. Each value is an array reference, ordered
# by the card order in the database # by the card order in the database
#
my %cards = ( 'pc600' => [ 'second from left','third from left', my %cards = ( 'pc600' => [ 'second from left','third from left',
'second from right','rightmost','leftmost' ], 'second from right','rightmost','leftmost' ],
'pc850' => [ 'left port of dual card', 'right port of dual card', 'pc850' => [ 'left port of dual card', 'right port of dual card',
...@@ -25,16 +39,11 @@ my %cards = ( 'pc600' => [ 'second from left','third from left', ...@@ -25,16 +39,11 @@ my %cards = ( 'pc600' => [ 'second from left','third from left',
my %wires = ( Node => 'yellow', Control => 'red', Power => 'green', my %wires = ( Node => 'yellow', Control => 'red', Power => 'green',
Serial => 'white' ); Serial => 'white' );
my ($node, $card);
my $tbdb = "@TBDBNAME@";
# Options: v = verbose, d = debug # Options: v = verbose, d = debug
my %opt = ( v => 0, d => 0); my %opt = ( v => 0, d => 0);
getopts('vd',\%opt); getopts('vd',\%opt);
my $dbh = Mysql->connect("localhost",$tbdb,"script","none");
die "Unable to connect to database" unless $dbh;
if (@ARGV < 1) { if (@ARGV < 1) {
exit &usage; exit &usage;
...@@ -53,10 +62,11 @@ while (my $arg = shift @ARGV) { ...@@ -53,10 +62,11 @@ while (my $arg = shift @ARGV) {
} }
&debug("Sending query $query\n"); &debug("Sending query $query\n");
my $sth = $dbh->query($query);
my $result = DBQueryFatal($query);
if ($opt{v}) { if ($opt{v}) {
while (my @row = $sth->fetchrow) { while (my @row = $result->fetchrow) {
my $cardinfo = ${$cards{$row[8]}}[$row[1]]; my $cardinfo = ${$cards{$row[8]}}[$row[1]];
my $switchinfo = $switches{$row[2]}; my $switchinfo = $switches{$row[2]};
my $wireinfo = $wires{$row[7]}; my $wireinfo = $wires{$row[7]};
...@@ -65,12 +75,10 @@ while (my $arg = shift @ARGV) { ...@@ -65,12 +75,10 @@ while (my $arg = shift @ARGV) {
"$row[5] (length $row[6], color $wireinfo)\n"; "$row[5] (length $row[6], color $wireinfo)\n";
} }
} else { } else {
print $sth->as_string; print $result->as_string;
} }
} }
#print $sth->as_string();
sub debug { warn @_,"\n" if $opt{d}; } sub debug { warn @_,"\n" if $opt{d}; }
sub usage { sub usage {
......
#!/usr/local/bin/perl -w
if ($#ARGV < 0) {die("Usage: mac2if <mac|if> <mac|if> <...>\n");}
use Mysql;
my $dbh = Mysql->connect("localhost","@TBDBNAME@","script","none");
my @list = "";
my $n=0;
foreach my $mac ( @ARGV ) {
if ( $mac =~ /^(sh\d+)(-\d)?(:\d)?$/ ) {
my $node = $1. (defined $2 ? $2 : "-" );
$list[$n] .= "(node_id like '$node%')";
} elsif ( $mac =~ /^([a-zA-Z]+\d+):(\d+)$/ ) {
my $node=$1;
my $if=$2;
$list[$n] .= "(node_id='$node' and card='$if')";
} elsif ( $mac =~ /^([a-zA-Z]+\d+)$/ ) {
my $node=$1;
$list[$n] .= "(node_id='$node')";
} else {
$mac =~ s/^(\d):/0$1:/;
$mac =~ s/:(\d):/:0$1:/g;
$mac =~ s/://g;
$list[$n] ="MAC='\L$mac'";
}
$n++;
}
my $cond = join(" or ",@list);
#print "Using conditions '$cond'\n";
my $sth = $dbh->
query("select * from interfaces where $cond");
print $sth->as_string();
#!/usr/bin/perl -w #!/usr/bin/perl -w
#
# node_status - Updates the 'status' column in the nodes table to indicate
# whether nodes are pingable, etc.
# Intended to be run as a cronjob
# Requires 'fping' to be installed
#
############################## Defines and includes ############################## Defines and includes
my $fping = "/usr/local/sbin/fping"; # Path to fping my $fping = "/usr/local/sbin/fping"; # Path to fping
my $tbdb = "@TBDBNAME@";
use strict; use strict;
use Mysql; use English;
use IPC::Open2; use IPC::Open2;
############################## Connect to databse # Configure variables
my $dbh = Mysql->connect("localhost",$tbdb,"script","none"); use lib '@prefix@/lib';
if (!$dbh) { die ("Unable to connect to database $tbdb\n"); } use libdb;
#
# Only root and admins are allowed to use this script
#
if (($UID != 0) && (!TBAdmin())) {
die "Only root and admins are allowed to use this script\n";
}
############################## Get node list ############################## Get node list
my $query = "SELECT nodes.node_id, nodes.status, os_info.osfeatures " . my $query = "SELECT nodes.node_id, nodes.status, os_info.osfeatures " .
"FROM nodes LEFT JOIN os_info ON nodes.def_boot_osid = os_info.osid "; "FROM nodes LEFT JOIN os_info ON nodes.def_boot_osid = os_info.osid ";
my $sth = $dbh->query($query); my $result = DBQueryFatal($query);
if (!$sth) { die "Unable to get node list: " . $dbh->errmsg . "\n" };
############################## Determine pingable/unpingable nodes ############################## Determine pingable/unpingable nodes
my (@newlyUp, @newlyDown, @newlyPD, @newlyUnpingable) = (); my (@newlyUp, @newlyDown, @newlyPD, @newlyUnpingable) = ();
...@@ -25,7 +37,7 @@ my $fpingPID = &open2("FOUT","FIN","$fping"); # Throws an exception on failure ...@@ -25,7 +37,7 @@ my $fpingPID = &open2("FOUT","FIN","$fping"); # Throws an exception on failure
my %oldStatus = (); # Status of node from the DB, so we can tell if it changed my %oldStatus = (); # Status of node from the DB, so we can tell if it changed
while (my %row = $sth->fetchhash) { while (my %row = $result->fetchhash) {
my $node = $row{node_id}; my $node = $row{node_id};
if ($row{osfeatures} && ($row{osfeatures} =~ /ping/)) { if ($row{osfeatures} && ($row{osfeatures} =~ /ping/)) {
# We have a node that should be capable of returning pings # We have a node that should be capable of returning pings
...@@ -69,7 +81,6 @@ foreach (['down', @newlyDown], ['up', @newlyUp], ...@@ -69,7 +81,6 @@ foreach (['down', @newlyDown], ['up', @newlyUp],
if (@nodes) { if (@nodes) {
my $query = "UPDATE nodes SET status='$status' WHERE " . my $query = "UPDATE nodes SET status='$status' WHERE " .
join " OR ", map("node_id='$_'",@nodes); join " OR ", map("node_id='$_'",@nodes);
my $sth = $dbh->query($query); DBQueryFatal($query);
if (!$sth) { die "Unable to update node status: " . $dbh->errmsg . "\n" };
} }
} }
#!/usr/local/bin/perl -w #!/usr/local/bin/perl -w
if ($#ARGV < 0) {die("Usage: nodeip <node_id|if|IP> <node_id|if|IP> <...>\n");} #
# nodeip - Given a node, interface, or MAC address, print the interface
use Mysql; # information for that interface. If a node is given, all interfaces for
# that node are printed.
my $dbh = Mysql->connect("localhost","@TBDBNAME@","script","none"); #
#
# Configure variables
#
use lib '@prefix@/lib';
use libdb;
if ($#ARGV < 0) {
print "Usage: mac2if <mac|if> <mac|if> <...>\n";
print "<mac> is in the form xx:xx:xx:xx:xx:xx or xxxxxxxxxxxx\n";
print "<if> is in the form <node[:card]>\n";
exit(1);
}
my @list = ""; my @list = "";
my $n=0; my $n=0;
foreach my $node ( @ARGV ) {
if ( $node =~ /^(sh\d+)(-\d)?(:\d)?$/ ) { foreach my $mac ( @ARGV ) {
my $node_id = $1. (defined $2 ? $2 : "-" ); if ( $mac =~ /^(sh\d+)(-\d)?(:\d)?$/ ) {
$list[$n] .= "(node_id like '$node_id%')"; my $node = $1. (defined $2 ? $2 : "-" );
} elsif ( $node =~ /^(\w+\d+):(\d+)$/ ) { $list[$n] .= "(node_id like '$node%')";
my $node_id=$1; } elsif ( $mac =~ /^([a-zA-Z]+\d+):(\d+)$/ ) {
my $if=$2; my $node=$1;
$list[$n] .= "(node_id='$node_id' and card='$if')"; my $if=$2;
} elsif ( $node =~ /^(\w+\d+)$/ ) { $list[$n] .= "(node_id='$node' and card='$if')";
my $node_id=$1; } elsif ( $mac =~ /^([a-zA-Z]+\d+)$/ ) {
$list[$n] .= "(node_id='$node_id')"; my $node=$1;
} else { $list[$n] .= "(node_id='$node')";
$list[$n] ="node_id='$node' or IP='$node' or IPalias='$node'"; } else {
} $mac =~ s/^(\d):/0$1:/;
$n++; $mac =~ s/:(\d):/:0$1:/g;
$mac =~ s/://g;
$list[$n] ="MAC='\L$mac'";
}
$n++;
} }
my $cond = join(" or ",@list); my $cond = join(" or ",@list);
print "Using conditions '$cond'\n"; my $result = DBQueryFatal("select * from interfaces where $cond");
my $sth = $dbh->
query("select * from interfaces where $cond");
print $sth->as_string(); print $result->as_string();
# #
# This is the definitions file for Mac on Emulab.Net. # This is the definitions file for Mac on Emulab.Net.
# #
TBDBNAME=tbdb TBDBNAME=tbdb_ricci
WWWDEFS=ricci-emulab WWWDEFS=ricci-emulab
TBOPSEMAIL=ricci@cs.utah.edu TBOPSEMAIL=ricci@cs.utah.edu
TBLOGSEMAIL=ricci@cs.utah.edu TBLOGSEMAIL=ricci@cs.utah.edu
......
...@@ -5,13 +5,9 @@ ...@@ -5,13 +5,9 @@
# will create identical virt_* entries. Well, almost identical. The virtual # will create identical virt_* entries. Well, almost identical. The virtual
# ports get changed. # ports get changed.
use DBI;
use lib "@prefix@/lib"; use lib "@prefix@/lib";
use exitonwarn; use exitonwarn;
$TBDB = "@TBDBNAME@"; use libdb;
$dbh = DBI->connect("DBI:mysql:database=$TBDB;host=localhost") ||
die "Could not connect to DB.\n";
if ($#ARGV != 1) { if ($#ARGV != 1) {
print STDERR "Syntax: $0 pid eid\n"; print STDERR "Syntax: $0 pid eid\n";
...@@ -19,15 +15,29 @@ if ($#ARGV != 1) { ...@@ -19,15 +15,29 @@ if ($#ARGV != 1) {
} }
($pid,$eid) = @ARGV; ($pid,$eid) = @ARGV;
#
# Make sure they have access to the experiment
#
if ((!TBAdmin()) && (!ProjMember($pid))) {
die "You are not a member of project %pid";
}
#
# Make sure the experiment exists
#
if (!ExpState($pid,$eid)) {
die "There is no experiment $eid in project $pid\n";
}
print "source tb_compat.tcl\n"; print "source tb_compat.tcl\n";
print "set ns [new Simulator]\n"; print "set ns [new Simulator]\n";
$sth = $dbh->prepare("select ips,osid,cmd_line,rpms,deltas,startupcmd," . my $result = DBQueryFatal("select ips,osid,cmd_line,rpms,deltas,startupcmd," .
"tarfiles,vname,type,failureaction " . "tarfiles,vname,type,failureaction " .
"from virt_nodes where pid=\"$pid\" and eid=\"$eid\""); "from virt_nodes where pid=\"$pid\" and eid=\"$eid\"");
$sth->execute;
while (($ips,$osid,$cmdline,$rpms,$deltas,$startupcmd, while (($ips,$osid,$cmdline,$rpms,$deltas,$startupcmd,
$tarfiles,$vname,$type,$failureaction) = $sth->fetchrow_array) { $tarfiles,$vname,$type,$failureaction) = $result->fetchrow_array) {
print "set $vname [\$ns node]\n"; print "set $vname [\$ns node]\n";
foreach $ippair (split(" ",$ips)) { foreach $ippair (split(" ",$ips)) {
($port,$ip) = split(":",$ippair); ($port,$ip) = split(":",$ippair);
...@@ -48,19 +58,18 @@ while (($ips,$osid,$cmdline,$rpms,$deltas,$startupcmd, ...@@ -48,19 +58,18 @@ while (($ips,$osid,$cmdline,$rpms,$deltas,$startupcmd,
} }
print "tb-set-node-failure-action $vname $failureaction\n"; print "tb-set-node-failure-action $vname $failureaction\n";
} }
$sth->finish; $result->finish;
$sth = $dbh->prepare("select vname,delay,bandwidth,lossrate,member" . $result = DBQueryFatal("select vname,delay,bandwidth,lossrate,member" .
" from virt_lans where pid=\"$pid\" and eid=\"$eid\""); " from virt_lans where pid=\"$pid\" and eid=\"$eid\"");
$sth->execute;
%lans = (); %lans = ();
while (($vname,$delay,$bw,$loss,$member) = $sth->fetchrow_array) { while (($vname,$delay,$bw,$loss,$member) = $result->fetchrow_array) {
if (!defined($lans{$vname})) { if (!defined($lans{$vname})) {
$lans{$vname} = []; $lans{$vname} = [];
} }
push(@{$lans{$vname}},[$member,$delay,$bw,$loss]); push(@{$lans{$vname}},[$member,$delay,$bw,$loss]);
} }
$sth->finish; $result->finish;
foreach $lan (keys(%lans)) { foreach $lan (keys(%lans)) {
$raw = ""; $raw = "";
foreach $member (@{$lans{$lan}}) { foreach $member (@{$lans{$lan}}) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment