Commit 5a7a1916 authored by Christopher Alfeld's avatar Christopher Alfeld

Ported handle_os.tcl to handle_os (PERL). In the process added a lot of

error checking and now pulls defaults from the database.  Also fixed a
bug in set-dnard-os with ranges and set-node-os now takes a PERL regex as
a nodespec (actually translates to the regexp /^nodespec$/).

Note: handle_os currently has the delay node OS hardcoded to
FBSD40-STD.  This should eventually come from the database.

Also the error checking is not completely tested yet.  However, the
correct case works and handle_os.tcl had no error checking.
parent b151c9ba
#!/usr/bin/perl -w
# This handles all the OS TB commands:
# create-os
# set-dnard-os
# set-node-os
# Yet to do:
# Any sort of delta support
push(@INC,"/usr/testbed/lib/tbsetup/ir");
require libir;
if ($#ARGV != 1) {
print STDERR "Syntax: $0 ir_file ns_file\n";
exit 1;
}
($irfile,$nsfile) = @ARGV;
use DBI;
$driver = "mysql";
$dbh = DBI->connect("DBI:$driver:database=tbdb;host=localhost")
|| die "Could not connect to DB.\n";
# List of ERROR messages
@ERRORS = ();
# read IR file
eval {&ir_read($irfile)};
if ($@) {
print STDERR "Could not read $irfile ($@)\n";
exit(1);
}
# open the ns file
open(NSFILE,$nsfile) || do {
print STDERR "Could not open $nsfile.\n";
exit(1);
};
# Load the node types and grab the default OS from the database
# %nodetype is indexed by virtual node id and contains the type
# %defaultos is indexed by type and contains the default OS
# $delayos is the delay os, currently assumed to be os of PC's
# XXX - Should grab this from the DB eventually
$delayos = "FBSD40-STD";
$raw = eval {&ir_get("/topology/nodes")};
if ($@) {
print STDERR "Could not load /topology/nodes.\n";
exit(1);
}
foreach (split("\n",$raw)) {
@info = split;
$node = $info[0];
$type = $info[1];
$nodetype{$node} = $type;
if (! defined($ostype{$type})) {
# Special case - shark shelf
if ($type eq "shark-shelf") {
$subtype = "shark";
} else {
$subtype = $type;
}
$sth = $dbh->prepare("SELECT image_id from node_types where type = \"$subtype\"");
$rr = $sth->execute;
if ($rr == 0) {
push(@ERRORS,"Invalid type $type");
$ostype{$type} = "INVALID";
} else {
@result = $sth->fetchrow_array;
$ostype{$type} = $result[0];
}
$sth->finish;
}
}
# Load the nodemap and set up an initial os table
# nodemap is indexed by virtual node id and contains the physical node id
# os is indexed by physical node id and contains the image id
$raw = eval {&ir_get("/virtual/nodes")};
if ($@) {
print STDERR "Could not load /virtual/nodes. Run assign first.\n";
exit(1);
}
foreach (split("\n",$raw)) {
($virtual,$physical) = split;
$nodemap{$virtual} = $physical;
if (!defined($nodetype{$virtual})) {
# assume to be a delay node
$os{$physical} = $delayos;
} else {
$os{$physical} = $ostype{$nodetype{$virtual}};
}
}
# Now we parse the NS file
# %images is indexed by label and contains "$path $partition"
while (<NSFILE>) {
/^\#TB/ || next;
chop;
@line = split;
$_ = $line[1];
SWITCH: {
/^create-os$/ && do {
# Should add some checking for partition
if ($#line != 4) {
push(@ERRORS,"Syntax: create-os label path partition");
} else {
($label,$path,$partition) = @line[2..4];
$images{$label} = "$path $partition";
}
last SWITCH;
};
/^set-dnard-os$/ && do {
if ($#line != 4) {
push(@ERRORS,"Syntax: set-dnard-os shelf n os");
} else {
($shelf,$n,$label) = @line[2..4];
if (! defined($nodemap{$shelf})) {
push(@ERRORS,"Unknown node $shelf\n");
last SWITCH;
}
if (! (($n =~ /[0-9]-[0-9]/) || ($n =~ /[0-9]/))) {
push(@ERRORS,"n must either be a number or a range start-end\n");
last SWITCH;
}
# The label should either be in the images table or
# in the DB.
if (! defined($images{$label})) {
# Check DB
$sth = $dbh->prepare("SELECT image_id from disk_images where image_id = \"$label\"");
$rr = $sth->execute;
if ($rr == 0) {
# Bad OS
$sth->finish;
push(@ERRORS,"Unknown OS label $label");
last SWITCH;
}
$sth->finish;
}
$prefix = $nodemap{$shelf};
if ($n =~ /[0-9]-[0-9]/) {
($start,$end) = split("-",$n);
foreach ($start..$end) {
$os{"$prefix-$_"}=$label;
}
} else {
$os{"$prefix-$n"}=$label;
}
}
last SWITCH;
};
/^set-node-os$/ && do {
if ($#line != 3) {
push(@ERRORS,"Syntax: set-node-os nodespec os");
} else {
($nodespec,$label) = @line[2..3];
# Do initial checking on label
# We also get the valid type for this image and store it
# in valid_type;
if (! defined($images{$label})) {
# Check DB
$sth = $dbh->prepare("SELECT type from disk_images where image_id = \"$label\"");
$rr = $sth->execute;
if ($rr == 0) {
# Bad OS
$sth->finish;
push(@ERRORS,"Unknown OS label $label");
last SWITCH;
} else {
@result = $sth->fetchrow_array;
$sth->finish;
$valid_type = $result[0];
}
} else {
# Custom image - don't know type info
$valid_type = "";
}
foreach (keys(%nodemap)) {
if (eval("/^$nodespec" . '$' . "/")) {
# Special case, make sure we aren't talking about sharks
if ($nodetype{$_} eq "shark-shelf") {
push(@ERRORS,"Use set-dnard-os for setting os of shark shelf $_\n");
} elsif (($valid_type ne "") &&
($nodetype{$_} ne $valid_type)) {
push(@ERRORS,"$_ is of type $nodetype($_), OS $label is of type $valid_type");
$os{$nodemap{$_}} = "INVALID";
} else {
$os{$nodemap{$_}} = $label;
}
}
}
}
last SWITCH;
};
/^set-dnard-deltas$/ && do {
# PLACE HOLDER
last SWITCH;
};
/^set-node-deltas$/ && do {
# PLACE HOLDER
last SWITCH;
};
}
}
# Check if we're good so far
if ($#ERRORS != -1) {
foreach (@ERRORS) {
print STDERR $_ . "\n";
}
exit(1);
}
# Let's do some output
# We allow running this on an IR file that has already been handle_os'ed
# it simply overwrites in that case.
if (! &ir_exists("/os")) {
# Fresh file, just append
open(IRFILE,">> $irfile") || do {
print STDERR "Could not open $irfile for appending.\n";
exit(1);
};
print IRFILE "START os\n";
print IRFILE "START images\n";
foreach (sort(keys(%images))) {
print IRFILE "$_ $images{$_}\n";
}
print IRFILE "END images\n";
print IRFILE "START nodes\n";
foreach (sort(keys(%os))) {
print IRFILE "$_ $os{$_}\n";
}
print IRFILE "END nodes\n";
print IRFILE "END os\n";
close(IRFILE);
} else {
# Here we use libir to overwrite the sections.
$images_raw = "";
foreach (sort(keys(%images))) {
$images_raw .= "$_ $images{$_}\n";
}
&ir_set("/os/images",$images_raw);
$nodes_raw = "";
foreach (sort(keys(%os))) {
$nodes_raw .= "$_ $os{$_}\n";
}
&ir_set("/os/nodes",$nodes_raw);
eval {&ir_write($irfile)};
if ($@) {
print STDERR "Could not write $irfile ($@)\n";
exit(1);
}
}
#!/usr/local/bin/tclsh
#XXX - Add DB checking
#XXX - Move this to the database
set DEFAULT_OS FBSD40-STD
if {[llength $argv] != 2} {
puts stderr "Syntax: $argv0 ir_file ns_file"
exit 1
}
set scriptdir [file dirname [info script]]
set updir [file dirname $scriptdir]
source "$scriptdir/libir.tcl"
if {[file exists $updir/../lib/sql.so]} {
load $updir/../lib/sql.so
} else {
load $updir/../sql.so
}
namespace import TB_LIBIR::ir
set DB [sql connect]
sql selectdb $DB tbdb
set nsfile [lindex $argv 1]
set irfile [lindex $argv 0]
ir read $irfile
if {! [ir exists /virtual/nodes]} {
puts stderr "Missing /virtual/nodes. Run assign first."
exit 1
}
set nmap [ir get /virtual/nodes]
foreach pair $nmap {
set node_map([lindex $pair 0]) [lindex $pair 1]
set os([lindex $pair 1]) $DEFAULT_OS
}
set fp [open $nsfile r]
#
# Verify that the OS is valid for the node. Return zero if not supported.
#
# XXX Checks for PCs in the DB disk_images table or in the local images table.
# Need to add support for the sharks.
#
proc checkimage {node label} {
global DB
global images
#
# DB holds our supported OS images.
#
sql query $DB "select image_id from disk_images \
where type='pc' and image_id='$label'"
if {[sql fetchrow $DB] != {}} {
sql endquery $DB
return 1;
}
sql endquery $DB
#
# Check local images table for a match.
#
foreach n [array names images] {
if {[string match $n $label] == 1} {
return 1;
}
}
return 0;
}
while {[gets $fp line] >= 0} {
if {[lindex $line 0] != "#TB"} {continue}
switch [lindex $line 1] {
"create-os" {
set label [lindex $line 2]
set path [lindex $line 3]
set partition [lindex $line 4]
set images($label) [list $path $partition]
}
"set-dnard-os" {
set shelf [lindex $line 2]
set n [lindex $line 3]
set label [lindex $line 4]
# XXX Check valid OS. Should either be in images
# or DB
set prefix $node_map($shelf)
if {[regexp {([0-9])-([0-9])} $n match s e] == 1} {
for {set i $s} {$i <= $e} {incr i} {
set os($prefix-$i) $label
}
}
}
"set-node-os" {
set node [lindex $line 2]
set label [lindex $line 3]
foreach n [array names node_map] {
if {[string match $node $n] == 1} {
if {[checkimage $node $label] == 1} {
set os($node_map($n)) $label
} else {
puts stderr "Invalid OS spec for $node:$label."
exit 1
}
}
}
}
"set-dnard-deltas" {
# Place holder
}
"set-node-deltas" {
# Place holder
}
default {
# NOP
}
}
}
# output
if {! [ir exists /os]} {
set fp [open $irfile a]
puts $fp "START os"
puts $fp "START images"
foreach i [array names images] {
puts $fp "$i $images($i)"
}
puts $fp "END images"
puts $fp "START nodes"
foreach n [array names os] {
puts $fp "$n $os($n)"
}
puts $fp "END nodes"
puts $fp "END os"
close $fp
} else {
set nodes_raw {}
foreach n [array names os] {
lappend nodes_raw "$n $os($n)"
}
set images_raw {}
foreach i [array names images] {
lappend images_raw "$i $images($i)"
}
ir set /os/nodes $nodes_raw
ir set /os/images $images_raw
ir write $irfile
}
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