Commit 25855415 authored by Russ Fish's avatar Russ Fish

Change the delaycontrol page to call delay_config via XML.

      www/delaycontrol.php3 - Convert the form into SPITFORM/submit/formfields.
                Add a ChangeDelayConfig function to spit out XML to delay_config.
      account/delay_config.in - Add -X <xmlfile> in place of other command-line args.
      sql/database-fill.sql - Add a couple of 'virt_lans' entries for delay_config's use.
parent 9a4f622f
......@@ -615,6 +615,7 @@ REPLACE INTO table_regex VALUES ('virt_agents','eid','text','redirect','experime
REPLACE INTO table_regex VALUES ('virt_agents','vname','text','redirect','eventlist:vname',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_agents','vnode','text','regex','^([-\\w]+)|(\\*{1})$',1,32,NULL);
REPLACE INTO table_regex VALUES ('virt_agents','objecttype','int','redirect','default:tinyint',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','vname','text','redirect','virt_nodes:vname',0,0,NULL);
......@@ -653,6 +654,9 @@ REPLACE INTO table_regex VALUES ('virt_lans','trace_expr','text','redirect','def
REPLACE INTO table_regex VALUES ('virt_lans','trace_snaplen','int','redirect','default:int',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_endnode','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_db','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','modify','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','compat','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','vname','text','redirect','virt_nodes:vname',0,0,NULL);
......@@ -833,9 +837,9 @@ REPLACE INTO table_regex VALUES ('node_types','issimnode','text','redirect','def
REPLACE INTO table_regex VALUES ('node_types','attr_name','text','regex','^[-\\w]+$',1,32,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_osid','text','redirect','os_info:osid',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_imageid','text','redirect','images:imageid',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_boolean','text','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_integer','text','redirect','default:int',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_float','text','redirect','default:float',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_boolean','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_integer','int','redirect','default:int',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_float','float','redirect','default:float',0,0,NULL);
REPLACE INTO table_regex VALUES ('node_types','attr_string','text','redirect','default:tinytext',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','security_level','int','redirect','default:tinyuint',0,4,NULL);
......@@ -918,6 +922,7 @@ REPLACE INTO table_regex VALUES ('os_info','osfeatures','text','regex','^[-\\w,]
REPLACE INTO table_regex VALUES ('os_info','op_mode','text','regex','^[-\\w]*$',1,20,NULL);
REPLACE INTO table_regex VALUES ('os_info','nextosid','text','redirect','os_info:osid',0,0,NULL);
REPLACE INTO table_regex VALUES ('os_info','reboot_waittime','int','redirect','default:int',0,2000,NULL);
REPLACE INTO table_regex VALUES ('sitevariables','name','text','regex','^[\\w\\/]+$',1,255,NULL);
REPLACE INTO table_regex VALUES ('sitevariables','value','text','redirect','default:text',0,0,NULL);
REPLACE INTO table_regex VALUES ('sitevariables','reset','text','redirect','default:boolean',0,0,NULL);
......
......@@ -8,6 +8,7 @@
use English;
use Getopt::Std;
use XML::Simple;
#
# Change delay params for a link.
......@@ -17,6 +18,7 @@ sub usage()
print(STDERR
"Usage: delay_config [-m] [-d] [-s vnode] <pid> <eid> <link>".
" PARAM=VALUE ...\n".
" delay_config [-d] -X <xmlfile>\n".
"Required: pid, eid, link, and at least one parameter to change!\n".
" pid = Project ID\n".
" eid = Experiment ID\n".
......@@ -26,6 +28,7 @@ sub usage()
" -d = turn on debugging\n".
" -s = Select the source of the link to determine which pipe\n".
" -m = Modify the base experiment in addition to current state.\n".
" -X = Get args and parameters from an XML file.\n".
"Parameters:\n".
" BANDWIDTH=NNN - N=bandwidth (10-100000 Kbits per second)\n",
" PLR=NNN - N=lossrate (0 <= plr < 1)\n".
......@@ -40,7 +43,7 @@ sub usage()
# Web interface cares about this return value!
exit(2);
}
my $optlist = "dms:c";
my $optlist = "dms:cX:";
#
# Configure variables
......@@ -49,8 +52,18 @@ my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TEVC = "$TB/bin/tevc";
my $GENTOPO = "$TB/libexec/gentopofile";
my $debug = 0;
my $compatmode = 0;
# Locals
my $pid;
my $eid;
my $link;
my $modify = 0;
my $srcvnode;
my %config;
my $pipeno;
my $pipe;
my $debug = 0;
my $compatmode = 0;
#
# Testbed Support libraries
......@@ -59,6 +72,42 @@ use lib "@prefix@/lib";
use libdb;
use libtestbed;
#
# Function prototypes
#
sub ChangeDelayConfig();
sub ChangeLinkDelayConfig();
sub ChangeVirtLans();
sub ParseXmlArgs($$$$$$);
sub fatal($);
#
# These are the fields that we allow to come in from the XMLfile.
#
my $SLOT_OPTIONAL = 0x1; # The field is not required.
my $SLOT_REQUIRED = 0x2; # The field is required and must be non-null.
my $SLOT_ADMINONLY = 0x4; # Only admins can set this field.
my $this_user; # Used for $SLOT_ADMINONLY.
my %xmlfields =
# XML Field Name DB slot name Flags Default
("pid" => ["pid", $SLOT_REQUIRED],
"eid" => ["eid", $SLOT_REQUIRED],
"link" => ["vname", $SLOT_REQUIRED],
"vnode" => ["vnode", $SLOT_OPTIONAL],
"modify" => ["modbase", $SLOT_OPTIONAL, 0],
"compat" => ["compat", $SLOT_OPTIONAL, 0],
"bandwidth" => ["bandwidth", $SLOT_OPTIONAL],
"plr" => ["lossrate", $SLOT_OPTIONAL],
"delay" => ["delay", $SLOT_OPTIONAL],
"limit" => ["q_limit", $SLOT_OPTIONAL],
"queue-in-bytes" => ["q_bytes", $SLOT_OPTIONAL],
"thresh" => ["q_maxthresh", $SLOT_OPTIONAL],
"minthresh" => ["q_minthresh", $SLOT_OPTIONAL],
"linterm" => ["q_linterm", $SLOT_OPTIONAL],
"q_weight" => ["q_weight", $SLOT_OPTIONAL]);
#
# Turn off line buffering on output
#
......@@ -74,9 +123,6 @@ delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
if (@ARGV < 4) {
usage();
}
%options = ();
if (! getopts($optlist, \%options)) {
usage();
......@@ -87,23 +133,57 @@ if (defined($options{"d"})) {
if (defined($options{"c"})) {
$compatmode = 1;
}
if (!defined($options{"X"})) {
my $pid = shift(@ARGV);
my $eid = shift(@ARGV);
my $link = shift(@ARGV);
}
else {
$xmlfile = $options{"X"};
my %xmlargs = ();
my %errors = ();
ParseXmlArgs($xmlfile, "virt_lans", \%xmlfields, $debug,
\%xmlargs, \%errors);
if (keys(%errors)) {
foreach my $errkey (keys(%errors)) {
my $errval = $errors{$errkey};
print "${errkey}: $errval\n";
}
fatal("XML arg error");
}
# Functions
sub ChangeDelayConfig();
sub ChangeLinkDelayConfig();
sub ChangeVirtLans();
# Locals
my $pid = shift(@ARGV);
my $eid = shift(@ARGV);
my $link = shift(@ARGV);
my $modify = 0;
my $srcvnode;
my %config;
my $pipeno;
my $pipe;
# There should be no other trailing args along with -X <xmlfile>.
usage()
if (@ARGV > 0);
foreach my $arg (keys(%xmlargs)) {
# Required.
if ($arg eq "pid") {
$pid = $xmlargs{"pid"};
}
elsif ($arg eq "eid") {
$eid = $xmlargs{"eid"};
}
elsif ($arg eq "link") {
$link = $xmlargs{"link"};
}
# Optional.
elsif ($arg eq "modify") {
$modify = $xmlargs{"modify"};
}
elsif ($arg eq "compat") {
$compatmode = $xmlargs{"compat"};
}
elsif ($arg eq "vnode") {
$srcvnode = $xmlargs{"vnode"};
}
# Push parameters onto ARGV for handling below.
else {
push(@ARGV, "$arg=" . $xmlargs{$arg});
}
}
}
if (defined($options{"m"})) {
$modify = 1;
}
......@@ -117,6 +197,10 @@ if (defined($options{"s"})) {
die("*** Bad srcvnode name: $srcvnode.\n");
}
}
if (@ARGV < 4 && !defined($options{"X"}) ) {
usage();
}
#
# Untaint args.
#
......@@ -680,3 +764,95 @@ sub ChangeVirtLans() {
" $GENTOPO failed!\n");
}
}
sub ParseXmlArgs($$$$$$) {
my ($xmlfile, $table_name, $fields_ref, $debug,
$args_ref, $errs_ref) = @_;
#
# Input args:
# $xmlfile - XML file path.
# $table_name - table_regex table_name for low-level checking patterns.
# $fields_ref - xmlfields specification (hash reference.)
# $debug
#
# Output args:
# $args_ref - Parsed argument values (hash reference.)
# $errs_ref - Error messages on failure (hash reference.)
#
# Must wrap the parser in eval since it exits on error.
#
my $xmlparse = eval { XMLin($xmlfile,
VarAttr => 'name',
ContentKey => '-content',
SuppressEmpty => undef); };
if ($@) {
$errs_ref->{"XML Parse Error"} = "Return code $@";
return;
}
#
# Make sure all the required arguments were provided.
#
my $key;
foreach $key (keys(%{ $fields_ref })) {
my (undef, $required, undef) = @{$fields_ref->{$key}};
$errs_ref->{$key} = "Required value not provided"
if ($required & $SLOT_REQUIRED &&
! exists($xmlparse->{'attribute'}->{"$key"}));
}
return
if (keys(%{ $errs_ref }));
foreach $key (keys(%{ $xmlparse->{'attribute'} })) {
my $value = $xmlparse->{'attribute'}->{"$key"}->{'value'};
if ($debug) {
print STDERR "User attribute: '$key' -> '$value'\n";
}
$errs_ref->{$key} = "Unknown attribute"
if (!exists($fields_ref->{$key}));
my ($dbslot, $required, $default) = @{$fields_ref->{$key}};
if ($required & $SLOT_REQUIRED) {
# A slot that must be provided, so do not allow a null value.
if (!defined($value)) {
$errs_ref->{$key} = "Must provide a non-null value";
next;
}
}
if ($required & $SLOT_OPTIONAL) {
# Optional slot. If value is null skip it. Might not be the correct
# thing to do all the time?
if (!defined($value)) {
next
if (!defined($default));
$value = $default;
}
}
if ($required & $SLOT_ADMINONLY) {
# Admin implies optional, but thats probably not correct approach.
$errs_ref->{$key} = "Administrators only"
if (! $this_user->IsAdmin());
}
# Now check that the value is legal.
if (! TBcheck_dbslot($value, $table_name, $dbslot,
TBDB_CHECKDBSLOT_ERROR)) {
$errs_ref->{$key} = TBFieldErrorString();
next;
}
$args_ref->{$key} = $value;
}
}
sub fatal($) {
my($mesg) = $_[0];
die("*** $0:\n".
" $mesg\n");
}
This diff is collapsed.
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