Commit 9ecc55d5 authored by Jonathon Duerig's avatar Jonathon Duerig

Merge branch 'rack-new'

Conflicts:
	install/genirack/GNUmakefile.in
parents 279a3546 7620208d
......@@ -31,7 +31,7 @@ include $(OBJDIR)/Makeconf
BIN_SCRIPTS = newosid moduserinfo newgroup newmmlist editexp editimageid \
editnodetype editsitevars newimageid editgroup \
newimageid_ez joinproject
newimageid_ez joinproject newscript
WEB_BIN_SCRIPTS = webnewosid webmoduserinfo webnewgroup webnewmmlist \
webeditexp webeditimageid webeditnodetype webeditsitevars \
webnewimageid webeditgroup webnewimageid_ez
......
......@@ -76,7 +76,7 @@ use OSinfo;
sub fatal($);
sub UserError(;$);
sub PrintResult($);
sub ModifyRow($);
sub ModifyRow($$);
sub RemoveRow($);
sub ResolveRow($);
sub CommitNode($);
......@@ -188,7 +188,8 @@ my %ifacefields =
"port" => ["port", $SLOT_OPTIONAL, undef],
"mac" => ["mac", $SLOT_OPTIONAL, undef],
"type" => ["interface_type", $SLOT_OPTIONAL, undef],
"role" => ["role", $SLOT_OPTIONAL, undef]);
"role" => ["role", $SLOT_OPTIONAL, undef],
"IP" => ["IP", $SLOT_OPTIONAL, undef]);
my %wirefields =
# XML Field Name DB slot name Flags Default
......@@ -384,9 +385,9 @@ exit(0)
my $rowlist;
if ($args{"command"} eq "add") {
ModifyRow(undef);
ModifyRow($id, 0);
} elsif ($args{"command"} eq "update") {
ModifyRow($id);
ModifyRow($id, 1);
} elsif ($args{"command"} eq "rollback") {
RemoveRow($id);
} elsif ($args{"command"} eq "commit") {
......@@ -447,12 +448,12 @@ sub PrintResult($)
}
}
sub ModifyRow($)
sub ModifyRow($$)
{
my ($id) = @_;
my ($id, $isupdate) = @_;
my $query;
my $none_changed = 1;
if (defined($id)) {
if ($isupdate) {
$query = "UPDATE";
} else {
$query = "INSERT";
......@@ -460,7 +461,8 @@ sub ModifyRow($)
$query .= " $tabledb SET";
foreach $key (keys(%args)) {
my $value = $args{$key};
if ($key ne "table" && $key ne "command" && $key ne $tableid
if ($key ne "table" && $key ne "command"
&& (! $isupdate || $key ne $tableid)
&& defined($value)) {
if ($query ne "UPDATE $tabledb SET"
&& $query ne "INSERT $tabledb SET") {
......@@ -470,7 +472,7 @@ sub ModifyRow($)
$none_changed = 0;
}
}
if (defined($id)) {
if ($isupdate) {
$query .= " WHERE $tableid='$id'";
}
if ($none_changed == 1) {
......@@ -556,9 +558,12 @@ sub CommitWire
while (my ($skip, $cable, $len, $type, $node_id1, $card1, $port1,
$node_id2, $card2, $port2) = $result->fetchrow()) {
my $query = "INSERT wires SET ".
"cable='$cable', len='$len', type='$type', node_id1='$node_id1', ".
"len='$len', type='$type', node_id1='$node_id1', ".
"card1='$card1', port1='$port1', node_id2='$node_id2', ".
"card2='$card2', port2='$port2'";
if (defined($cable)) {
$query .= ", cable='$cable'";
}
if ($fake) {
print $query."\n";
} else {
......
......@@ -27,7 +27,7 @@ SUBDIR = install/genirack
include $(OBJDIR)/Makeconf
TARGETS = initnodes.pl initilo.pl
TARGETS = initnodes.pl initilo.pl mknewconfig
#
# Force dependencies on the scripts so that they will be rerun through
......
Make sure this is not an 'elabinelab' installation on defs file.
Enable ScriptNewNodes feature:
/usr/testbed/sbin/wap /usr/testbed/sbin/emulabfeature create ScriptNewNodes "Enable scripting for newnodes"
/usr/testbed/sbin/wap /usr/testbed/sbin/emulabfeature enable ScriptNewNodes
Run mknewconfig in your object directory:
/usr/testbed/sbin/wap ../obj/install/genirack/mknewconfig config ip.txt USE249NFXY.XML wiring.xml
#!/usr/bin/perl
use XML::LibXML;
use XML::LibXML::XPathContext;
use XML::LibXML::NodeList;
use Carp qw(cluck carp);
use lib "@prefix@/lib";
use User;
my $TB = "@prefix@";
my $NEWSCRIPT = "$TB/bin/newscript";
if (scalar(@ARGV) != 4) {
fatal("Usage: mknewconfig <out-path> <ip-file> <hp-xml> <wiring-file>\n");
}
my $outpath = shift(@ARGV);
my $ipfile = shift(@ARGV);
my $hpfile = shift(@ARGV);
my $wiringfile = shift(@ARGV);
#
# Can only be invoked by Admin.
#
$this_user = User->ThisUser();
if (! defined($this_user)) {
fatal("You ($UID) do not exist!");
} elsif (!$this_user->IsAdmin()) {
fatal("You must have admin privledges to create new nodes");
}
# Make sure outpath exists
system("mkdir -p $outpath");
# Load IP data
#
# Each line should be <node_id> <control_ip> <ilo_ip>
# Node id should be one of (pc1, pc2, pc3, pc4, pc5).
open(IP, "<$ipfile");
my @iplist = <IP>;
my %control_ips = {};
my %ilo_ips = {};
foreach my $line (@iplist) {
chomp($line);
my @fields = split(/ /, $line);
my $node_id = $fields[0];
my $control = $fields[1];
my $ilo = $fields[2];
$control_ips{$node_id} = $control;
$ilo_ips{$node_id} = $ilo;
}
close(IP);
my %devices = ();
# Load node data
my $hpdoc = XML::LibXML->load_xml( location => $hpfile );
foreach my $node ($hpdoc->documentElement()->find("Device")->get_nodelist()) {
my @maclist = ();
push(@maclist, GetText("nic1mac", $node));
push(@maclist, GetText("nic2mac", $node));
push(@maclist, GetText("nic3mac", $node));
push(@maclist, GetText("nic4mac", $node));
my $blob = {
'location' => GetText("u_location", $node),
'ilomac' => GetText("lo_mac", $node),
'maclist' => \@maclist
};
if ($blob->{'location'} ne "n/a" &&
$blob->{'location'} ne "U34") {
$devices{$blob->{'location'}} = $blob;
}
}
my @wires = ();
# Load wires/interfaces data
my $wiringdoc = XML::LibXML->load_xml( location => $wiringfile );
foreach my $node ($wiringdoc->documentElement()->find("./wire")->get_nodelist()) {
my $node_id = GetText('node_id1', $node);
my $id;
if ($node_id =~ /pc([0-9])/) {
$id = $1;
}
my $location = GetText('UXX', $node);
$devices{$location}->{'id'} = $id;
$devices{$location}->{'node_id'} = $node_id;
my $blob = {
'id' => $id,
'node_id' => $node_id,
'location' => $location,
'iface' => GetText('iface', $node),
'role' => GetText('role', $node),
'card' => GetText('card1', $node),
'port' => GetText('port1', $node),
'switch' => GetText('node_id2', $node),
'switch_card' => GetText('card2', $node),
'switch_port' => GetText('port2', $node),
};
push(@wires, $blob);
}
# Print nodes
foreach my $current (values(%devices)) {
my $id = $current->{'id'};
my $node_id = $current->{'node_id'};
if (! exists($control_ips{$node_id})) {
print STDERR "No IP address for node: $node_id\n";
next;
}
my $ip = $control_ips{$node_id};
my $file = "$outpath/node.$node_id";
open(NODE_FILE, ">$file");
print NODE_FILE "<newnode>\n";
print NODE_FILE " <attribute name='table'><value>node</value></attribute>\n";
print NODE_FILE " <attribute name='command'><value>add</value></attribute>\n";
if (defined($id)) {
print NODE_FILE " <attribute name='id'><value>$id</value></attribute>\n";
}
print NODE_FILE " <attribute name='node_id'><value>$node_id</value></attribute>\n";
print NODE_FILE " <attribute name='type'><value>dl360</value></attribute>\n";
print NODE_FILE " <attribute name='IP'><value>$ip</value></attribute>\n";
print NODE_FILE " <attribute name='identifier'><value>$node_id</value></attribute>\n";
print NODE_FILE "</newnode>\n";
close(NODE_FILE);
print STDERR "Adding node $node_id\n";
system("$NEWSCRIPT < $file");
}
# Print interfaces
foreach my $current (@wires) {
my $id = $current->{'id'};
my $node_id = $current->{'node_id'};
my $card = $current->{'card'};
my $port = $current->{'port'};
my $location = $current->{'location'};
my $device = $devices{$location};
my $mac;
my $role = $current->{'role'};
my $type = "bce";
if ($role eq "mngmnt") {
$type = "ilo3";
$mac = $device->{'ilomac'};
} else {
my @maclist = @{ $device->{'maclist'} };
$mac = $maclist[$card];
}
my $file = "$outpath/iface.$node_id.$card.$port";
open(IF_FILE, ">$file");
print IF_FILE "<newinterface>\n";
print IF_FILE " <attribute name='table'><value>interface</value></attribute>\n";
print IF_FILE " <attribute name='command'><value>add</value></attribute>\n";
print IF_FILE " <attribute name='node_id'><value>$id</value></attribute>\n";
print IF_FILE " <attribute name='card'><value>$card</value></attribute>\n";
print IF_FILE " <attribute name='port'><value>$port</value></attribute>\n";
print IF_FILE " <attribute name='mac'><value>$mac</value></attribute>\n";
print IF_FILE " <attribute name='type'><value>$type</value></attribute>\n";
print IF_FILE " <attribute name='role'><value>$role</value></attribute>\n";
if ($role eq "mngmnt" && exists($ilo_ips{$node_id})) {
my $IP = $ilo_ips{$node_id};
print IF_FILE " <attribute name='IP'><value>$IP</value></attribute>\n";
}
print IF_FILE "</newinterface>\n";
close(IF_FILE);
print STDERR "Adding interface $node_id.$card.$port\n";
system("$NEWSCRIPT < $file");
}
# Commit nodes
foreach my $current (values(%devices)) {
my $node_id = $current->{'node_id'};
my $id = $current->{'id'};
my $file = "$outpath/node.$node_id.commit";
open(NODE_FILE, ">$file");
print NODE_FILE "<newnode>\n";
print NODE_FILE " <attribute name='table'><value>node</value></attribute>\n";
print NODE_FILE " <attribute name='command'><value>commit</value></attribute>\n";
print NODE_FILE " <attribute name='id'><value>$id</value></attribute>\n";
print NODE_FILE "</newnode>\n";
close(NODE_FILE);
print STDERR "Committing node $node_id\n";
system("$NEWSCRIPT < $file");
sleep(3);
}
# Print wires
my $wireid = 1;
foreach my $current (@wires) {
my $node_id = $current->{'node_id'};
my $card = $current->{'card'};
my $port = $current->{'port'};
my $switch = $current->{'switch'};
my $switch_card = $current->{'switch_card'};
my $switch_port = $current->{'switch_port'};
my $role = $current->{'role'};
my $type = "Node";
if ($role eq "ctrl") {
$type = "Control";
} elsif ($role eq "mngmnt") {
$type = "Management";
}
my $file = "$outpath/wire.$node_id.$card.$port";
open(WIRE_FILE, ">$file");
print WIRE_FILE "<newwire>\n";
print WIRE_FILE " <attribute name='table'><value>wire</value></attribute>\n";
print WIRE_FILE " <attribute name='command'><value>add</value></attribute>\n";
print WIRE_FILE " <attribute name='id'><value>$wireid</value></attribute>\n";
print WIRE_FILE " <attribute name='len'><value>0</value></attribute>\n";
print WIRE_FILE " <attribute name='type'><value>$type</value></attribute>\n";
print WIRE_FILE " <attribute name='node_id1'><value>$node_id</value></attribute>\n";
print WIRE_FILE " <attribute name='card1'><value>$card</value></attribute>\n";
print WIRE_FILE " <attribute name='port1'><value>$port</value></attribute>\n";
print WIRE_FILE " <attribute name='node_id2'><value>$switch</value></attribute>\n";
print WIRE_FILE " <attribute name='card2'><value>$switch_card</value></attribute>\n";
print WIRE_FILE " <attribute name='port2'><value>$switch_port</value></attribute>\n";
print WIRE_FILE "</newwire>\n";
close(WIRE_FILE);
print STDERR "Adding wire $node_id.$card.$port\n";
system("$NEWSCRIPT < $file");
$file = "$outpath/wire.$node_id.$card.$port.commit";
open(WIRE_FILE, ">$file");
print WIRE_FILE "<newwire>\n";
print WIRE_FILE " <attribute name='table'><value>wire</value></attribute>\n";
print WIRE_FILE " <attribute name='command'><value>commit</value></attribute>\n";
print WIRE_FILE " <attribute name='id'><value>$wireid</value></attribute>\n";
print WIRE_FILE "</newwire>\n";
close(WIRE_FILE);
print STDERR "Committing wire $node_id.$card.$port\n";
system("$NEWSCRIPT < $file");
++$wireid;
}
# Get the text contents of a child of a node with a particular
# name. This can be either an attribute or an element.
sub GetText($$)
{
my ($name, $node) = @_;
my $result = undef;
my $child = FindFirst('@n:'.$name, $node);
if (! defined($child)) {
$child = FindFirst('@'.$name, $node);
}
if (! defined($child)) {
$child = FindFirst('n:'.$name, $node);
}
if (defined($child)) {
$result = $child->textContent();
}
return $result;
}
# Returns the first Node which matches a given XPath.
sub FindFirst($$)
{
my ($path, $node) = @_;
return FindNodes($path, $node)->pop();
}
# Returns a NodeList for a given XPath using a given node as
# context. 'n' is defined to be the prefix for the namespace of the
# node.
sub FindNodes($$)
{
my ($path, $node) = @_;
my $result = undef;
my $ns = undef;
eval {
my $xc = XML::LibXML::XPathContext->new();
$ns = $node->namespaceURI();
if (defined($ns)) {
$xc->registerNs('n', $ns);
} else {
$path =~ s/\bn://g;
}
$result = $xc->findnodes($path, $node);
};
if ($@) {
if (! defined($ns)) {
$ns = "undefined";
}
cluck "Failed to find nodes using XPath path='$path', ns='$ns': $@\n";
return XML::LibXML::NodeList->new();
} else {
return $result;
}
}
<wiring>
<wire>
<UXX>U05</UXX>
<node_id1>pc1</node_id1>
<iface>eth0</iface>
<role>ctrl</role>
<card1>0</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>1</port2>
</wire>
<wire>
<UXX>U05</UXX>
<node_id1>pc1</node_id1>
<iface>eth1</iface>
<role>expt</role>
<card1>1</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>1</port2>
</wire>
<wire>
<UXX>U05</UXX>
<node_id1>pc1</node_id1>
<iface>eth2</iface>
<role>expt</role>
<card1>2</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>2</port2>
</wire>
<wire>
<UXX>U05</UXX>
<node_id1>pc1</node_id1>
<iface>eth3</iface>
<role>expt</role>
<card1>3</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>3</port2>
</wire>
<wire>
<UXX>U05</UXX>
<node_id1>pc1</node_id1>
<iface>ilo3</iface>
<role>mngmnt</role>
<card1>99</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>2</port2>
</wire>
<wire>
<UXX>U06</UXX>
<node_id1>pc2</node_id1>
<iface>eth0</iface>
<role>ctrl</role>
<card1>0</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>3</port2>
</wire>
<wire>
<UXX>U06</UXX>
<node_id1>pc2</node_id1>
<iface>eth1</iface>
<role>expt</role>
<card1>1</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>4</port2>
</wire>
<wire>
<UXX>U06</UXX>
<node_id1>pc2</node_id1>
<iface>eth2</iface>
<role>expt</role>
<card1>2</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>5</port2>
</wire>
<wire>
<UXX>U06</UXX>
<node_id1>pc2</node_id1>
<iface>eth3</iface>
<role>expt</role>
<card1>3</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>6</port2>
</wire>
<wire>
<UXX>U06</UXX>
<node_id1>pc2</node_id1>
<iface>ilo3</iface>
<role>mngmnt</role>
<card1>99</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>4</port2>
</wire>
<wire>
<UXX>U07</UXX>
<node_id1>pc3</node_id1>
<iface>eth0</iface>
<role>ctrl</role>
<card1>0</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>6</port2>
</wire>
<wire>
<UXX>U07</UXX>
<node_id1>pc3</node_id1>
<iface>eth1</iface>
<role>expt</role>
<card1>1</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>7</port2>
</wire>
<wire>
<UXX>U07</UXX>
<node_id1>pc3</node_id1>
<iface>eth2</iface>
<role>expt</role>
<card1>2</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>8</port2>
</wire>
<wire>
<UXX>U07</UXX>
<node_id1>pc3</node_id1>
<iface>eth3</iface>
<role>expt</role>
<card1>3</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>9</port2>
</wire>
<wire>
<UXX>U07</UXX>
<node_id1>pc3</node_id1>
<iface>ilo3</iface>
<role>mngmnt</role>
<card1>99</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>6</port2>
</wire>
<wire>
<UXX>U08</UXX>
<node_id1>pc4</node_id1>
<iface>eth0</iface>
<role>ctrl</role>
<card1>0</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>7</port2>
</wire>
<wire>
<UXX>U08</UXX>
<node_id1>pc4</node_id1>
<iface>eth1</iface>
<role>expt</role>
<card1>1</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>10</port2>
</wire>
<wire>
<UXX>U08</UXX>
<node_id1>pc4</node_id1>
<iface>eth2</iface>
<role>expt</role>
<card1>2</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>11</port2>
</wire>
<wire>
<UXX>U08</UXX>
<node_id1>pc4</node_id1>
<iface>eth3</iface>
<role>expt</role>
<card1>3</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>12</port2>
</wire>
<wire>
<UXX>U08</UXX>
<node_id1>pc4</node_id1>
<iface>ilo3</iface>
<role>mngmnt</role>
<card1>99</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>8</port2>
</wire>
<wire>
<UXX>U09</UXX>
<node_id1>pc5</node_id1>
<iface>eth0</iface>
<role>ctrl</role>
<card1>0</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>9</port2>
</wire>
<wire>
<UXX>U09</UXX>
<node_id1>pc5</node_id1>
<iface>eth1</iface>
<role>expt</role>
<card1>1</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>13</port2>
</wire>
<wire>
<UXX>U09</UXX>
<node_id1>pc5</node_id1>
<iface>eth2</iface>
<role>expt</role>
<card1>2</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>14</port2>
</wire>
<wire>
<UXX>U09</UXX>
<node_id1>pc5</node_id1>
<iface>eth3</iface>
<role>expt</role>
<card1>3</card1>
<port1>1</port1>
<node_id2>procurve2</node_id2>
<card2>1</card2>
<port2>15</port2>
</wire>
<wire>
<UXX>U09</UXX>
<node_id1>pc5</node_id1>
<iface>ilo3</iface>
<role>mngmnt</role>
<card1>99</card1>
<port1>1</port1>
<node_id2>procurve1</node_id2>
<card2>1</card2>
<port2>10</port2>
</wire>
</wiring>
......@@ -2293,6 +2293,7 @@ CREATE TABLE `new_interfaces` (
`cable` smallint(6) default NULL,
`len` tinyint(4) default NULL,
`role` tinytext,
`IP` varchar(15) default NULL,
PRIMARY KEY (`new_interface_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
......
#
# Add IP slot to new_interfaces table
#
use strict;
use libdb;
my $impotent = 0;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (!DBSlotExists("new_interfaces", "IP")) {
DBQueryFatal("alter table new_interfaces add ".
" `IP` varchar(15) default NULL");
}
return 0;
}
1;
......@@ -232,7 +232,7 @@ NODE: foreach my $node_id (@node_ids) {
# Grab the node's MACs from the new_interfaces table
#
$query_result = DBQueryFatal("SELECT card, MAC, interface_type, " .
"switch_id, switch_card, switch_port, cable, len, role, port " .
"switch_id, switch_card, switch_port, cable, len, role, port, IP " .
"FROM new_interfaces WHERE new_node_id='$new_node_id'");
if (!$query_result->num_rows()) {
warn "Node $node_id failed: Must have at least one interface!\n";
......@@ -241,7 +241,7 @@ NODE: foreach my $node_id (@node_ids) {
my %interfaces;
while (my ($card, $MAC, $iface_type, $switch_id, $switch_card,
$switch_port, $cable, $len, $ifrole, $port) = $query_result->fetchrow()) {
$switch_port, $cable, $len, $ifrole, $port, $iface_IP) = $query_result->fetchrow()) {
#
# Get some more information about this interface type
#
......@@ -273,7 +273,8 @@ NODE: foreach my $node_id (@node_ids) {
# Stash it away...
#
$interfaces{$card} = [$MAC, $iface_type, $max_speed, $full_duplex,
$switch_id, $switch_card, $switch_port, $cable, $len, $ifrole, $port];
$switch_id, $switch_card, $switch_port, $cable,
$len, $ifrole