Commit dc90a087 authored by Leigh Stoller's avatar Leigh Stoller

Changes to reservation system wrt classic interface:

1. Reservation system now groks experiment lockdown and swappable. When
   swapping in, lockdown and swappable mean the expected end of the
   experiment is never.

2. Reservation library now handles changes to lockdowm, swappable, and
   autoswap (timeout). editexp now hands these changes off to a new
   script called manage_expsettings, which can be called by hand since
   we might need to force a change (I am not changing the classic UI, if
   a change is not allowed by the res system, we have to do it by hand).

3. Minor fixes to reservation library.
parent d5a924c5
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -43,9 +43,10 @@ my $verify = 0; # Check data and return status only.
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@";
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@";
my $MANAGESETTINGS = "$TB/sbin/manage_expsettings";
#
# Untaint the path
......@@ -63,6 +64,7 @@ $| = 1;
#
use lib "@prefix@/lib";
use libdb;
use emutil;
use libtestbed;
use User;
use Project;
......@@ -153,6 +155,7 @@ my %xmlfields =
# The rest are optional, so we can skip passing ones that are not changing
"description" => ["description", $SLOT_OPTIONAL],
"idle_ignore" => ["idle_ignore", $SLOT_OPTIONAL],
"lockdown" => ["lockdown", $SLOT_OPTIONAL],
"swappable" => ["swappable", $SLOT_OPTIONAL],
"noswap_reason" => ["noswap_reason", $SLOT_OPTIONAL],
"idleswap" => ["idleswap", $SLOT_OPTIONAL],
......@@ -304,6 +307,8 @@ if (!defined($experiment)) {
if (!$experiment->AccessCheck($this_user, TB_EXPT_MODIFY())) {
UserError("Experiment: Not enough permission");
}
my $pid = $experiment->pid();
my $eid = $experiment->eid();
#
# Description must not be blank.
......@@ -330,32 +335,124 @@ if (exists($editexp_args{"idle_ignore"})) {
}
}
#
# Lockdown
#
if (exists($editexp_args{"lockdown"})) {
my $requested = ($editexp_args{"lockdown"} eq "1" ? 1 : 0);
if ($requested != $experiment->lockdown()) {
if ($editexp_args{"lockdown"} eq "1" && !$this_user->IsAdmin()) {
UserError("lockdown: Only Administrators can lockdown experiments");
}
#
# New path; have to deal with this via the reservation system.
#
my $which = ($requested ? "set" : "clear");
my $output = emutil::ExecQuiet("$MANAGESETTINGS ".
"lockdown $pid,$eid $which");
if ($?) {
my $rval = $? >> 8;
if ($rval == 1) {
UserError("lockdown: locking down this experiment would ".
"cause a reservation system overbook situation");
}
else {
print STDERR $output;
fatal($output);
}
}
}
delete($editexp_args{"lockdown"});
}
#
# Swappable
#
if (exists($editexp_args{"swappable"})) {
if ($editexp_args{"swappable"} ne "1") {
$editexp_args{"swappable"} = 0;
# Turning off swappable, must provide justification.
if ((exists($editexp_args{"noswap_reason"}) ?
$editexp_args{"noswap_reason"} eq "" :
$experiment->noswap_reason() eq "")) {
if (!$this_user->IsAdmin()) {
UserError("Swappable: No justification provided");
my $requested = ($editexp_args{"swappable"} eq "0" ? 0 : 1);
if ($requested != $experiment->swappable()) {
if ($requested == 0 && !$this_user->IsAdmin()) {
UserError("swappable: Only Administrators can turn off swappable");
}
#
# New path; have to deal with this via the reservation system.
#
my $which = ($requested ? "set" : "clear");
my $output = emutil::ExecQuiet("$MANAGESETTINGS ".
"swappable $pid,$eid $which");
if ($?) {
my $rval = $? >> 8;
if ($rval == 1) {
UserError("swappable: disabling swappable would ".
"cause a reservation system overbook situation");
}
else {
$editexp_args{"noswap_reason"} = "ADMIN";
print STDERR $output;
fatal($output);
}
}
if ($experiment->swappable()) {
$doemail = 1;
}
}
delete($editexp_args{"swappable"});
}
if (exists($editexp_args{"noswap_reason"})) {
$editexp_args{"noswap_reason"} =
escapeshellarg($editexp_args{"noswap_reason"});
#
# AutoSwap
#
my $autoswap_max = TBGetSiteVar("general/autoswap_max");
if (exists($editexp_args{"autoswap"}) ||
exists($editexp_args{"autoswap_timeout"})) {
my $hours;
my $which;
if (exists($editexp_args{"autoswap"})) {
my $requested = ($editexp_args{"autoswap"} eq "1" ? 1 : 0);
if ($requested != $experiment->autoswap()) {
if ($requested == 0 && !$this_user->IsAdmin()) {
UserError("Max Duration: ".
"Only Administrators can turn off Max Duration");
}
$which = ($requested ? "set" : "clear");
}
}
if (exists($editexp_args{"autoswap_timeout"})) {
my $requested = $editexp_args{"autoswap_timeout"};
if ($requested != $experiment->autoswap_timeout()) {
if ($requested <= 0) {
UserError("Max Duration: Invalid time provided");
}
if ($requested > $autoswap_max && !$this_user->IsAdmin()) {
UserError("Max Duration: $autoswap_max hours maximum - ".
"you must ask testbed operations for more");
}
$hours = $editexp_args{"autoswap_timeout"};
}
}
if (defined($hours) || defined($which)) {
# If only changing the timeout, we still need a set/clear argument.
$which = ($experiment->autoswap() ? "set" : "clear")
if (!defined($which));
$hours = "" if (!defined($hours));
my $output = emutil::ExecQuiet("$MANAGESETTINGS ".
"autoswap $pid,$eid $which $hours");
if ($?) {
my $rval = $? >> 8;
if ($rval == 1) {
UserError("autoswap: modifying autoswap would ".
"cause a reservation system overbook situation");
}
else {
print STDERR $output;
fatal($output);
}
}
}
delete($editexp_args{"autoswap"});
delete($editexp_args{"autoswap_timeout"});
}
#
......@@ -396,30 +493,6 @@ if (exists($editexp_args{"noidleswap_reason"})) {
escapeshellarg($editexp_args{"noidleswap_reason"});
}
#
# AutoSwap
#
if (exists($editexp_args{"autoswap"})) {
if ($editexp_args{"autoswap"} ne "1") {
if (!$this_user->IsAdmin()) {
UserError("Max Duration: ".
"you must ask testbed operations to disable this");
}
$editexp_args{"autoswap"} = 0;
}
}
my $autoswap_max = TBGetSiteVar("general/autoswap_max");
if (exists($editexp_args{"autoswap_timeout"})) {
if ($editexp_args{"autoswap_timeout"} <= 0) {
UserError("Max Duration: Invalid time provided");
}
if ($editexp_args{"autoswap_timeout"} > $autoswap_max &&
!$this_user->IsAdmin()) {
UserError("Max Duration: $autoswap_max hours maximum - ".
"you must ask testbed operations for more");
}
}
#
# Swapout disk state saving
#
......
......@@ -1231,8 +1231,8 @@ sub EditExp($$$$$$)
($mods{"autoswap_timeout"} = $argref->{"autoswap_timeout"});
}
foreach my $col ("idle_ignore", "swappable", "noswap_reason",
"idleswap", "noidleswap_reason", "autoswap", "savedisk",
foreach my $col ("idle_ignore", "noswap_reason",
"idleswap", "noidleswap_reason", "savedisk",
"cpu_usage", "mem_usage", "linktest_level") {
# Copy args we want so that others can't get through.
if (exists($argref->{$col})) {
......@@ -1254,7 +1254,6 @@ sub EditExp($$$$$$)
return undef;
}
}
my $creator = $experiment->creator();
my $swapper = $experiment->swapper();
my $uid = $user->uid();
......@@ -1262,11 +1261,7 @@ sub EditExp($$$$$$)
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;
}
return 1;
}
# Do not send this email if the user is an administrator
# (adminmode does not matter), and is changing an expt he created
......@@ -3238,6 +3233,69 @@ sub SetPanicBit($$)
return 0;
}
sub SetSwappable($$)
{
my ($self, $arg) = @_;
my $idx = $self->idx();
my $onoff = ($arg ? 1 : 0);
return -1
if (!DBQueryWarn("update experiments set ".
" swappable='$onoff' ".
"where idx='$idx'"));
$self->{'EXPT'}->{'swappable'} = $onoff;
return 0;
}
sub SetLockdown($$)
{
my ($self, $arg) = @_;
my $idx = $self->idx();
my $onoff = ($arg ? 1 : 0);
return -1
if (!DBQueryWarn("update experiments set ".
" lockdown='$onoff' ".
"where idx='$idx'"));
$self->{'EXPT'}->{'lockdown'} = $onoff;
return 0;
}
sub SetAutoswap($$)
{
my ($self, $arg) = @_;
my $idx = $self->idx();
my $onoff = ($arg ? 1 : 0);
return -1
if (!DBQueryWarn("update experiments set ".
" autoswap='$onoff' ".
"where idx='$idx'"));
$self->{'EXPT'}->{'lockdown'} = $onoff;
return 0;
}
sub SetAutoswapTimeout($$)
{
my ($self, $minutes) = @_;
my $idx = $self->idx();
return -1
if (!DBQueryWarn("update experiments set ".
" autoswap_timeout='$minutes' ".
"where idx='$idx'"));
$self->{'EXPT'}->{'autoswap_timeout'} = $minutes;
return 0;
}
#
# Is experiment firewalled?
#
......
This diff is collapsed.
......@@ -189,9 +189,9 @@ my $endtime = Reservation->ExpectedEnd( $experiment );
# low-level library routines; this is a horrible violation of abstraction;
# and it's all MySQL's fault...
if( $PGENISUPPORT ) {
DBQueryFatal("lock tables reserved write, users read, groups read, projects read, future_reservations read, nodes as n read, reserved as r read, experiments as e read, next_reserve as nr read, `geni-cm`.geni_slices as s read, project_reservations as pr read, reservation_version write");
DBQueryFatal("lock tables reserved write, users read, groups read, projects read, future_reservations read, nodes as n read, reserved as r read, experiments as e read, experiment_stats as stats read, next_reserve as nr read, `geni-cm`.geni_slices as s read, project_reservations as pr read, reservation_version write");
} else {
DBQueryFatal("lock tables reserved write, users read, groups read, projects read, future_reservations read, nodes as n read, reserved as r read, experiments as e read, next_reserve as nr read, project_reservations as pr read, reservation_version write");
DBQueryFatal("lock tables reserved write, users read, groups read, projects read, future_reservations read, nodes as n read, reserved as r read, experiments as e read, experiment_stats as stats read, next_reserve as nr read, project_reservations as pr read, reservation_version write");
}
TBDebugTimeStamp("nalloc locked tables");
......
......@@ -67,7 +67,7 @@ SBIN_STUFF = resetvlans console_setup.proxy sched_reload named_setup \
rmproj pool_daemon \
checknodes_daemon snmpit.proxyv3 image_setup tcpp \
arplockdown bscontrol reportboot reportboot_daemon \
nfsmfs_setup nfsmfs_setup.proxy
nfsmfs_setup nfsmfs_setup.proxy manage_expsettings
ifeq ($(ISMAINSITE),1)
SBIN_STUFF += repos_daemon
......
This diff is collapsed.
<?php
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -146,6 +146,27 @@ function SPITFORM($experiment, $formfields, $errors)
</td>
</tr>\n";
#
# Lockdown
#
echo " <tr>
<td>
<input type=checkbox
name='formfields[lockdown]'
value=1";
if (isset($formfields["lockdown"]) &&
strcmp($formfields["lockdown"], "1") == 0) {
echo " checked='1'";
}
echo ">
</td>
<td>
Lockdown
</td>
</tr>\n";
echo " <tr>
<td>
<input type='checkbox'
......@@ -346,6 +367,7 @@ function SPITFORM($experiment, $formfields, $errors)
#
$defaults = array();
$defaults["description"] = $experiment->description();
$defaults["lockdown"] = $experiment->lockdown();
$defaults["idle_ignore"] = $experiment->idle_ignore();
$defaults["batchmode"] = $experiment->batchmode();
$defaults["swappable"] = $experiment->swappable();
......@@ -399,6 +421,13 @@ if ($isadmin) { # A couple of admin-only options.
$args["idle_ignore"] = $formfields["idle_ignore"];
}
$formfields["lockdown"] =
(!isset($formfields["lockdown"]) ||
strcmp($formfields["lockdown"], "1")) ? 0 : 1;
if ($formfields["lockdown"] != $experiment->lockdown()) {
$args["lockdown"] = $formfields["lockdown"];
}
$formfields["swappable"] = (!isset($formfields["swappable"]) ||
strcmp($formfields["swappable"], "1")) ? 0 : 1;
if ($formfields["swappable"] != $experiment->swappable()) {
......
......@@ -447,20 +447,6 @@ class Experiment
return ($success ? 0 : -1);
}
#
# Flip lockdown bit.
#
function SetLockDown($mode) {
$idx = $this->idx();
$mode = ($mode ? 1 : 0);
$query_result =
DBQueryFatal("update experiments set lockdown='$mode' ".
"where idx='$idx'");
return 0;
}
#
# Flip lockdown bit.
#
......@@ -1081,17 +1067,6 @@ class Experiment
</tr>\n";
}
if (ISADMIN()) {
$lockflip = ($lockdown ? 0 : 1);
$lockval = ($lockdown ? "Yes" : "No");
echo "<tr>
<td>Locked Down:</td>
<td>$lockval (<a href='toggle.php?pid=$pid&eid=$eid".
"&type=lockdown&value=$lockflip'>Toggle</a>)
</td>
</tr>\n";
}
if (ISADMIN() || STUDLY() || OPSGUY()) {
$thisflip = ($skipvlans ? 0 : 1);
$flipval = ($skipvlans ? "Yes" : "No");
......
<?php
#
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -189,17 +189,6 @@ elseif ($type == "widearearoot") {
$zapurl = CreateURL("showuser", $target_user);
$target_user->SetWideAreaRoot($value);
}
elseif ($type == "lockdown") {
# must be admin
if (! $isadmin) {
USERERROR("You do not have permission to toggle $type!", 1);
}
if (! ($experiment = Experiment::LookupByPidEid($pid, $eid))) {
PAGEARGERROR("Experiment $pid/$eid is not a valid experiment!");
}
$zapurl = CreateURL("showexp", $experiment);
$experiment->SetLockDown($value);
}
elseif ($type == "skipvlans") {
# Must validate the pid,eid since we allow non-admins to do this.
if (! TBvalid_pid($pid)) {
......
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