All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 187ec0f9 authored by Russ Fish's avatar Russ Fish

Move editexp page form logic to a backend Perl script.

     www/editexp.php3 - The reworked PHP page.
     backend/{editexp,GNUmakefile}.in configure configure.in - New backend script.
     www/experiment_defs.php - Add an Experiment::EditExp class method
                               bridging to the script via XML.
     db/Experiment.pm.in - Add an EditExp worker class method for script arg checking,
                           And a missing description method.
     sql/database-fill.sql - Add to the table_regex 'experiments' checking patterns.
parent 363c05a3
......@@ -12,8 +12,8 @@ UNIFIED = @UNIFIED_BOSS_AND_OPS@
include $(OBJDIR)/Makeconf
BIN_SCRIPTS = moduserinfo newgroup newmmlist
WEB_BIN_SCRIPTS = webmoduserinfo webnewgroup webnewmmlist
BIN_SCRIPTS = moduserinfo newgroup newmmlist editexp
WEB_BIN_SCRIPTS = webmoduserinfo webnewgroup webnewmmlist webeditexp
WEB_SBIN_SCRIPTS=
LIBEXEC_SCRIPTS = $(WEB_BIN_SCRIPTS) $(WEB_SBIN_SCRIPTS)
......
This diff is collapsed.
......@@ -2428,7 +2428,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
account/addpubkey account/addsfskey account/genpubkeys \
account/quotamail account/mkusercert account/newproj account/newuser \
backend/GNUmakefile backend/moduserinfo backend/newgroup \
backend/newmmlist \
backend/newmmlist backend/editexp \
tbsetup/GNUmakefile tbsetup/console_setup tbsetup/spewlogfile \
tbsetup/spewrpmtar tbsetup/gentopofile tbsetup/power_sgmote.pm \
tbsetup/console_reset tbsetup/bwconfig tbsetup/power_rpc27.pm \
......
......@@ -808,7 +808,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
account/addpubkey account/addsfskey account/genpubkeys \
account/quotamail account/mkusercert account/newproj account/newuser \
backend/GNUmakefile backend/moduserinfo backend/newgroup \
backend/newmmlist \
backend/newmmlist backend/editexp \
tbsetup/GNUmakefile tbsetup/console_setup tbsetup/spewlogfile \
tbsetup/spewrpmtar tbsetup/gentopofile tbsetup/power_sgmote.pm \
tbsetup/console_reset tbsetup/bwconfig tbsetup/power_rpc27.pm \
......
......@@ -39,6 +39,7 @@ my $TBOPS = "@TBOPSEMAIL@";
my $PROJROOT = "@PROJROOT_DIR@";
my $EVENTSYS = @EVENTSYS@;
my $STAMPS = @STAMPS@;
my $TBBASE = "@TBBASE@";
my $TEVC = "$TB/bin/tevc";
my $DBCONTROL = "$TB/sbin/opsdb_control";
my $RSYNC = "/usr/local/bin/rsync";
......@@ -189,6 +190,7 @@ sub pid_idx($) { return field($_[0], 'pid_idx'); }
sub gid_idx($) { return field($_[0], 'gid_idx'); }
sub eid($) { return field($_[0], 'eid'); }
sub idx($) { return field($_[0], 'idx'); }
sub description($) { return field($_[0], 'expt_name'); }
sub path($) { return field($_[0], 'path'); }
sub state($) { return field($_[0], 'state'); }
sub batchstate($) { return field($_[0], 'batchstate'); }
......@@ -887,6 +889,194 @@ sub Update($$)
return Refresh($self);
}
#
# Worker class method to change experiment info.
# Assumes most argument checking was done elsewhere.
#
sub EditExp($$$$$$)
{
my ($class, $experiment, $user, $doemail, $argref, $usrerr_ref) = @_;
my %mods;
my $noreport;
my %updates;
#
# Converting the batchmode is tricky, but we can let the DB take care
# of it by requiring that the experiment not be locked, and it be in
# the swapped state. If the query fails, we know that the experiment
# was in transition.
#
if (!exists($argref->{"batchmode"})) {
$argref->{"batchmode"} = 0;
}
if ($experiment->batchmode() != $argref->{"batchmode"}) {
my $success = 0;
my $batchmode;
if ($argref->{"batchmode"} ne "1") {
$batchmode = 0;
$argref->{"batchmode"} = 0;
}
else {
$batchmode = 1;
$argref->{"batchmode"} = 1;
}
if ($experiment->SetBatchMode($batchmode) != 0) {
$$usrerr_ref = "Batch Mode: Experiment is running or in transition; ".
"try again later";
return undef;
}
$mods{"batchmode"} = $batchmode;
}
#
# Now update the rest of the information in the DB.
#
# Name change for experiment description.
if (exists($argref->{"description"})) {
$updates{"expt_name"} = ($mods{"description"} = $argref->{"description"});
}
# Note that timeouts are in hours in the UI, but in minutes in the DB.
if (exists($argref->{"idleswap_timeout"})) {
$updates{"idleswap_timeout"} = 60 *
($mods{"idleswap_timeout"} = $argref->{"idleswap_timeout"});
}
if (exists($argref->{"autoswap_timeout"})) {
$updates{"autoswap_timeout"} = 60 *
($mods{"autoswap_timeout"} = $argref->{"autoswap_timeout"});
}
foreach my $col ("idle_ignore", "swappable", "noswap_reason",
"idleswap", "noidleswap_reason", "autoswap", "savedisk",
"cpu_usage", "mem_usage", "linktest_level") {
# Copy args we want so that others can't get through.
if (exists($argref->{$col})) {
$updates{$col} = $mods{$col} = $argref->{$col};
}
}
# Save state before change for the email message below.
my $olds = ($experiment->swappable() ? "Yes" : "No");
my $oldsr= $experiment->noswap_reason();
my $oldi = ($experiment->idleswap() ? "Yes" : "No");
my $oldit= $experiment->idleswap_timeout() / 60.0;
my $oldir= $experiment->noidleswap_reason();
my $olda = ($experiment->autoswap() ? "Yes" : "No");
my $oldat= $experiment->autoswap_timeout() / 60.0;
if (keys %updates) {
if ($experiment->Update(\%updates)) {
return undef;
}
}
my $creator = $experiment->creator();
my $swapper = $experiment->swapper();
my $uid = $user->uid();
my $pid = $experiment->pid();
my $eid = $experiment->eid();
if (!keys %mods) {
if (!$noreport) {
# Warn the user that the submit button was pressed with no effect.
$$usrerr_ref = "Submit: Nothing changed";
return undef;
}
}
# Do not send this email if the user is an administrator
# (adminmode does not matter), and is changing an expt he created
# or swapped in. Pointless email.
elsif ( $doemail &&
! ($user->admin() &&
($uid eq $creator || $uid eq $swapper)) ) {
# Send an audit e-mail reporting what is being changed.
my $target_creator = $experiment->GetCreator();
my $target_swapper = $experiment->GetSwapper();
my $user_name = $user->name();
my $user_email = $user->email();
my $cname = $target_creator->name();
my $cemail = $target_creator->email();
my $sname = $target_swapper->name();
my $semail = $target_swapper->email();
my $s = ($experiment->swappable() ? "Yes" : "No");
my $sr = $experiment->noswap_reason();
my $i = ($experiment->idleswap() ? "Yes" : "No");
my $it = $experiment->idleswap_timeout() / 60.0;
my $ir = $experiment->noidleswap_reason();
my $a = ($experiment->autoswap() ? "Yes" : "No");
my $at = $experiment->autoswap_timeout() / 60.0;
my $msg = "\n".
"The swap settings for $pid/$eid have changed\n".
"\nThe old settings were:\n".
"Swappable:\t$olds\t($oldsr)\n".
"Idleswap:\t$oldi\t(after $oldit hrs)\t($oldir)\n".
"MaxDuration:\t$olda\t(after $oldat hrs)\n".
"\nThe new settings are:\n".
"Swappable:\t$s\t($sr)\n".
"Idleswap:\t$i\t(after $it hrs)\t($ir)\n".
"MaxDuration:\t$a\t(after $at hrs)\n".
"\nCreator:\t$creator ($cname <$cemail>)\n".
"Swapper:\t$swapper ($sname <$semail>)\n".
"\nDifferences were:\n";
my @report =
("Description:description", "Idle Ignore:idle_ignore",
"Swappable:swappable", "Noswap Reason:noswap_reason",
"Idleswap:idleswap", "Idleswap Timeout:idleswap_timeout",
"Noidleswap Reason:noidleswap_reason", "Autoswap:autoswap",
"Autoswap timeout:autoswap_timeout", "Savedisk:savedisk",
"Cpu Usage:cpu_usage", "Mem Usage:mem_usage",
"Batch Mode:batchmode", "Linktest Level:linktest_level");
foreach my $line (@report) {
my ($label, $field) = split /:/, $line;
if (exists($mods{$field})) {
$msg .= sprintf "%-20s%s\n", $label .":", $mods{$field};
}
}
$msg .= "\n".
"\nIf it is necessary to change these settings, ".
"please reply to this message \nto notify the user, ".
"then change the settings here:\n\n".
"$TBBASE/showexp.php3?pid=$pid&eid=$eid\n\n".
"Thanks,\nTestbed WWW\n";
SENDMAIL("$user_name <$user_email>",
"$pid/$eid swap settings changed",
$msg, TBMAIL_OPS(), sprintf("Bcc: %s\nErrors-To:%s",
TBMAIL_AUDIT(), TBMAIL_WWW()));
}
return 1;
}
sub SetBatchMode($$) {
my ($self, $mode) = @_;
my $reqstate = EXPTSTATE_SWAPPED();
my $idx = $self->idx();
$mode = ($mode ? 1 : 0);
DBQueryFatal("lock tables experiments write");
my $query_result =
DBQueryFatal("update experiments set ".
" batchmode=$mode ".
"where idx='$idx' and ".
" expt_locked is NULL and state='$reqstate'");
my $success = $query_result->numrows; # XXX Was DBAffectedRows().
dbqueryfatal("unlock tables");
return ($success ? 0 : -1);
}
#
# Stringify for output.
#
......
......@@ -562,8 +562,6 @@ REPLACE INTO table_regex VALUES ('experiments','uselatestwadata','int','redirect
REPLACE INTO table_regex VALUES ('experiments','wa_delay_solverweight','float','redirect','default:float',0,1024,NULL);
REPLACE INTO table_regex VALUES ('experiments','wa_bw_solverweight','float','redirect','default:float',0,1024,NULL);
REPLACE INTO table_regex VALUES ('experiments','wa_plr_solverweight','float','redirect','default:float',0,1024,NULL);
REPLACE INTO table_regex VALUES ('experiments','cpu_usage','int','redirect','default:tinyint',0,5,NULL);
REPLACE INTO table_regex VALUES ('experiments','mem_usage','int','redirect','default:tinyint',0,5,NULL);
REPLACE INTO table_regex VALUES ('experiments','sync_server','text','redirect','virt_nodes:vname',0,0,NULL);
REPLACE INTO table_regex VALUES ('groups','project','text','redirect','projects:pid',0,0,NULL);
......@@ -718,6 +716,7 @@ REPLACE INTO table_regex VALUES ('projects','num_members','int','redirect','defa
REPLACE INTO table_regex VALUES ('projects','num_pcs','int','redirect','default:int',0,2048,NULL);
REPLACE INTO table_regex VALUES ('projects','num_pcplab','int','redirect','default:int',0,2048,NULL);
REPLACE INTO table_regex VALUES ('projects','num_ron','int','redirect','default:int',0,1024,NULL);
REPLACE INTO table_regex VALUES ('experiments','encap_style','text','regex','^(alias|veth|veth-ne|vlan|default)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','veth_encapsulate','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','allowfixnode','int','redirect','default:boolean',0,0,NULL);
......@@ -726,14 +725,25 @@ REPLACE INTO table_regex VALUES ('experiments','delay_osname','text','redirect',
REPLACE INTO table_regex VALUES ('experiments','use_ipassign','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','ipassign_args','text','regex','^[\\w\\s-]*$',0,255,NULL);
REPLACE INTO table_regex VALUES ('experiments','expt_name','text','redirect','default:tinytext',1,255,NULL);
REPLACE INTO table_regex VALUES ('experiments','dpdb','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('experiments','description','text','regex','^[\\040-\\176\\012\\015\\011]*$',1,256,NULL);
REPLACE INTO table_regex VALUES ('experiments','idle_ignore','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','swappable','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','noswap_reason','text','redirect','default:tinytext',1,255,NULL);
REPLACE INTO table_regex VALUES ('experiments','noidleswap_reason','text','redirect','default:tinytext',1,255,NULL);
REPLACE INTO table_regex VALUES ('experiments','idleswap','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','idleswap_timeout','int','redirect','default:int',1,2147483647,NULL);
REPLACE INTO table_regex VALUES ('experiments','noidleswap_reason','text','redirect','default:tinytext',1,255,NULL);
REPLACE INTO table_regex VALUES ('experiments','autoswap','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','autoswap_timeout','int','redirect','default:int',1,2147483647,NULL);
REPLACE INTO table_regex VALUES ('experiments','savedisk','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','cpu_usage','int','redirect','default:tinyint',0,5,NULL);
REPLACE INTO table_regex VALUES ('experiments','mem_usage','int','redirect','default:tinyint',0,5,NULL);
REPLACE INTO table_regex VALUES ('experiments','batchmode','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','linktest_level','int','redirect','default:tinyint',0,4,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','protocol','text','redirect','default:tinytext',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','is_accesspoint','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('experiments','linktest_level','int','redirect','default:tinyint',0,4,NULL);
REPLACE INTO table_regex VALUES ('experiments','dpdb','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('virt_lan_settings','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lan_settings','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lan_settings','vname','text','redirect','virt_lans:vname',0,0,NULL);
......
This diff is collapsed.
......@@ -135,6 +135,80 @@ class Experiment
return 0;
}
#
# Class function to change experiment info via XML to a backend script.
#
function EditExp($experiment, $args, &$errors) {
global $suexec_output, $suexec_output_array;
if (!count($args)) {
$errors[] = "No changes to submit.";
return null;
}
#
# Generate a temporary file and write in the XML goo.
#
$xmlname = tempnam("/tmp", "editexp");
if (! $xmlname) {
TBERROR("Could not create temporary filename", 0);
$errors[] = "Transient error; please try again later.";
return null;
}
if (! ($fp = fopen($xmlname, "w"))) {
TBERROR("Could not open temp file $xmlname", 0);
$errors[] = "Transient error; please try again later.";
return null;
}
# Add these. Maybe caller should do this?
$args["experiment"] = $experiment->idx();
fwrite($fp, "<experiment>\n");
foreach ($args as $name => $value) {
fwrite($fp, "<attribute name=\"$name\">");
fwrite($fp, " <value>" . htmlspecialchars($value) . "</value>");
fwrite($fp, "</attribute>\n");
}
fwrite($fp, "</experiment>\n");
fclose($fp);
chmod($xmlname, 0666);
$retval = SUEXEC("nobody", "nobody", "webeditexp $xmlname",
SUEXEC_ACTION_IGNORE);
if ($retval) {
if ($retval < 0) {
$errors[] = "Transient error; please try again later.";
SUEXECERROR(SUEXEC_ACTION_CONTINUE);
}
else {
# unlink($xmlname);
if (count($suexec_output_array)) {
for ($i = 0; $i < count($suexec_output_array); $i++) {
$line = $suexec_output_array[$i];
if (preg_match("/^([-\w]+):\s*(.*)$/",
$line, $matches)) {
$errors[$matches[1]] = $matches[2];
}
else
$errors[] = $line;
}
}
else
$errors[] = "Transient error; please try again later.";
}
return null;
}
# There are no return value(s) to parse at the end of the output.
# Unlink this here, so that the file is left behind in case of error.
# We can then create the experiment by hand from the xmlfile, if desired.
unlink($xmlname);
return true;
}
#
# Update fields. Array of "foo=bar" ...
#
......
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