Commit f94e2952 authored by Leigh B Stoller's avatar Leigh B Stoller

Add reservation modification.

parent 5644a5ff
......@@ -190,25 +190,36 @@ sub DoReserve()
$checkonly = 1;
}
usage()
if (! (defined($project) && defined($count) && defined($type) &&
defined($start) && defined($end)));
if ($count !~ /^\d+$/) {
fatal("Count is not an integer");
if (!defined($project));
if (defined($update)) {
usage()
if (! (defined($count) || defined($start) || defined($end)));
}
if ($type !~ /^[-\w]+$/) {
fatal("Type is not a string");
else {
usage()
if (! (defined($count) && defined($type) &&
defined($start) && defined($end)));
if ($type !~ /^[-\w]+$/) {
fatal("Type is not a string");
}
}
if (defined($count) && $count !~ /^\d+$/) {
fatal("Count is not an integer");
}
if (! ($start =~ /^\d+$/ || str2time($start))) {
fatal("Start is not a datetime");
if (defined($start) &&
!($start =~ /^\d+$/ || str2time($start))) {
fatal("Start is not a unix timestamp or datetime");
}
if (! ($end =~ /^\d+$/ || str2time($end))) {
fatal("End is not a datetime");
if (defined($end) &&
!($end =~ /^\d+$/ || str2time($end))) {
fatal("End is not a unix timestamp or datetime");
}
$rpcargs{"start"} = TBDateStringGMT($start);
$rpcargs{"end"} = TBDateStringGMT($end);
$rpcargs{"count"} = $count;
$rpcargs{"type"} = $type;
$rpcargs{"start"} = TBDateStringGMT($start) if (defined($start));
$rpcargs{"end"} = TBDateStringGMT($end) if (defined($end));
$rpcargs{"count"} = $count if (defined($count));
$rpcargs{"type"} = $type if (!defined($update));
$rpcargs{"check"} = $checkonly;
$rpcargs{"reason"}= $reason if (defined($reason));
$rpcargs{"update"}= $update if (defined($update));
......
......@@ -636,67 +636,93 @@ sub Reserve($)
my $pid = $project->pid();
my $uid = $geniuser->emulab_user()->uid();
# Different rules for update.
my $update = (exists($argref->{"update"}) ? $argref->{"update"} : undef);
return GeniResponse->MalformedArgsResponse("Invalid update index")
if (defined($update) && $update !~ /^\d+$/);
#
# Required arguments.
# Required arguments when not an update.
#
foreach my $field ("count", "start", "end", "type") {
return GeniResponse->MalformedArgsResponse("Missing $field")
if (! (exists($argref->{$field}) && $argref->{$field} ne ""));
}
my $count = $argref->{"count"};
my $start = $argref->{"start"};
my $end = $argref->{"end"};
my $type = $argref->{"type"};
my ($count,$start,$end,$type);
if (!$update) {
foreach my $field ("count", "start", "end", "type") {
return GeniResponse->MalformedArgsResponse("Missing $field")
if (! (exists($argref->{$field}) && $argref->{$field} ne ""));
}
$count = $argref->{"count"};
$start = $argref->{"start"};
$end = $argref->{"end"};
$type = $argref->{"type"};
return GeniResponse->MalformedArgsResponse("Invalid type")
if ($type !~ /^[-\w]+$/);
my $nodetype = NodeType->Lookup($type);
return GeniResponse->SearchFailedResponse("No such node type")
if (!defined($type));
}
else {
my $okay = 0;
foreach my $field ("count", "start", "end") {
$okay = 1
if (exists($argref->{$field}) && $argref->{$field} ne "");
}
return GeniResponse->MalformedArgsResponse("Missing update arguments")
if (!$okay);
$count = $argref->{"count"} if (exists($argref->{"count"}));
$start = $argref->{"start"} if (exists($argref->{"start"}));
$end = $argref->{"end"} if (exists($argref->{"end"}));
}
my $check = (exists($argref->{"check"}) && $argref->{"check"} ? 1 : 0);
my $reason= (exists($argref->{"reason"}) ? $argref->{"reason"} : undef);
my $update= (exists($argref->{"update"}) ? $argref->{"update"} : undef);
return GeniResponse->MalformedArgsResponse("Invalid count")
if ($count !~ /^\d+$/);
return GeniResponse->MalformedArgsResponse("Invalid type")
if ($type !~ /^[-\w]+$/);
return GeniResponse->MalformedArgsResponse("Invalid update")
if (defined($update) && $update !~ /^\d+$/);
if (defined($count) && $count !~ /^\d+$/);
if (defined($reason) &&
!TBcheck_dbslot($reason, "default", "tinytext",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
return GeniResponse->MalformedArgsResponse("Invalid reason")
}
# Gack, why does Frontier do this. It is stupid.
if (ref($start) eq 'Frontier::RPC2::DateTime::ISO8601') {
$start = $start->value;
}
if (ref($end) eq 'Frontier::RPC2::DateTime::ISO8601') {
$end = $end->value;
}
# Convert to a localtime.
$start = eval { timegm(strptime($start)); };
if ($@) {
return GeniResponse->MalformedArgsResponse("Start time: $@");
}
return GeniResponse->MalformedArgsResponse("Start time: ".
"Could not parse date")
if (!defined($start));
$end = eval { timegm(strptime($end)); };
if ($@) {
return GeniResponse->MalformedArgsResponse("End time: $@");
if (defined($start)) {
# Gack, why does Frontier do this. It is stupid.
if (ref($start) eq 'Frontier::RPC2::DateTime::ISO8601') {
$start = $start->value;
}
# Convert to a localtime.
$start = eval { timegm(strptime($start)); };
if ($@) {
return GeniResponse->MalformedArgsResponse("Start time: $@");
}
return GeniResponse->MalformedArgsResponse("Start time: ".
"Could not parse date")
if (!defined($start));
}
if (defined($end)) {
# Gack, why does Frontier do this. It is stupid.
if (ref($end) eq 'Frontier::RPC2::DateTime::ISO8601') {
$end = $end->value;
}
$end = eval { timegm(strptime($end)); };
if ($@) {
return GeniResponse->MalformedArgsResponse("End time: $@");
}
return GeniResponse->MalformedArgsResponse("End time: ".
"Could not parse date")
if (!defined($end));
}
return GeniResponse->MalformedArgsResponse("End time: Could not parse date")
if (!defined($end));
my $nodetype = NodeType->Lookup($type);
return GeniResponse->SearchFailedResponse("No such type")
if (!defined($type));
#
# It would be great to check permission here if an update, but without
# a concept of remote admin, this is not possible.
#
if (defined($update)) {
my $reservation = Reservation->Lookup($update);
return GeniResponse->SearchFailedResponse("No such reservation")
if (!defined($reservation));
return GeniResponse->Create(GENIRESPONSE_FORBIDDEN)
if ($reservation->pid() ne $project->pid());
}
# Use a webtask to get back output.
......@@ -707,7 +733,11 @@ sub Reserve($)
my $args = ($check ? "-n " : "") .
(defined($update) ? "-m $update " : "") .
"-T " . $webtask->task_id() . " ".
"-U $uid -t $type -s $start -e $end $pid $count";
(defined($type) ? "-t $type " : "") .
(defined($start) ? "-s $start " : "") .
(defined($end) ? "-e $end " : "") .
(defined($update) && defined($count) ? "-S $count " : "") .
"-U $uid " . (!defined($update) ? "$pid $count" : "");
# Write the reason to a tempfile to pass in. This will auto unlink.
my $fp;
......@@ -723,6 +753,7 @@ sub Reserve($)
if ($?) {
GeniUtil::FlipToGeniUser();
print STDERR "$args\n";
$webtask->Refresh();
my $code = $webtask->code();
my $mesg = $webtask->output();
......
......@@ -54,7 +54,7 @@ $(function ()
projects: projlist,
amlist: amlist,
isadmin: isadmin,
editing: false,
editing: editing,
});
html = aptforms.FormatFormFieldsHorizontal(html);
$('#main-body').html(html);
......@@ -265,10 +265,11 @@ $(function ()
}
// Messy.
var details = json.value;
$('#reserve-request-form [name=idx]').val(details.idx);
$('#reserve-request-form [name=pid]').val(details.pid);
$('#reserve-request-form [name=count]').val(details.count);
$('#reserve-request-form [name=cluster]').val(details.cluster);
HandleClusterChange(details.cluster);
$('#reserve-request-form [name=cluster_id]').val(details.cluster_id);
$('#reserve-request-form [name=type]').val(details.type);
$('#reserve-request-form [name=reason]')
.val(_.escape(details.notes));
......
......@@ -115,8 +115,8 @@ function Do_Reserve()
#
# Update mode; we get the idx of the current reservation.
#
if (isset($ajax_args["idx"])) {
$idx = $ajax_args["idx"];
if (isset($formfields["idx"])) {
$idx = $formfields["idx"];
if (!TBvalid_integer($idx)) {
$errors["error"] = "Bad index for reservation update";
}
......@@ -141,7 +141,7 @@ function Do_Reserve()
# make sure it is allowed.
#
$args = "-t " . escapeshellarg($formfields["type"]) . " ".
(defined($idx) ? "-u $idx " : "") .
(isset($idx) ? "-u $idx " : "") .
"-s $start -e $end $pid " . $formfields["count"];
#
......@@ -415,6 +415,8 @@ function Do_GetReservation()
$blob["end"] = $details['end'];
$blob["notes"] = $details['notes'];
$blob["cluster"] = $aggregate->urn();
# For display.
$blob["cluster_id"] = $ajax_args["cluster"];
$webtask->Delete();
SPITAJAX_RESPONSE($blob);
}
......
......@@ -3,7 +3,8 @@
col-md-7'>
<div class='panel panel-default'>
<div class='panel-heading'>
<h3 class='panel-title'>Reservation Request</h3>
<h3 class='panel-title'>
<% if (editing) { %>Modify <% } %>Reservation Request</h3>
</div>
<div class='panel-body'>
<div>
......@@ -19,6 +20,8 @@
<% if (editing) { %>
<input id="idx" name="idx" type="hidden"
value=<%- formfields.idx %>>
<input id="cluster" name="cluster" type="hidden"
value=<%- formfields.cluster %>>
<% } %>
<div class='row'>
<div class='col-sm-12'>
......@@ -175,12 +178,12 @@
</div>
<div class="form-group">
<% if (editing) { %>
<input name="cluster" readonly
id="cluster"
value="<%- formfields.cluster %>"
<input name="cluster_id" readonly
id="cluster_id"
value="<%- formfields.cluster_id %>"
class="form-control format-me"
data-label="Cluster"
data-key="cluster">
data-key="cluster_id">
<% } else { %>
<select name="cluster"
id="cluster"
......@@ -202,15 +205,25 @@
<% } %>
</div>
<div class="form-group">
<select name="type"
id="type"
class='form-control format-me'
data-key="type"
data-label="Hardware Type"
placeholder='Please Select'
data-colsize="4">
<option value=''>Please Select</option>
</select>
<% if (editing) { %>
<input name="type" readonly
value="<%- formfields.type %>"
id="type"
class='form-control format-me'
data-key="type"
data-label="Hardware Type"
data-colsize="4">
<% } else { %>
<select name="type"
id="type"
class='form-control format-me'
data-key="type"
data-label="Hardware Type"
placeholder='Please Select'
data-colsize="4">
<option value=''>Please Select</option>
</select>
<% } %>
</div>
<div class="form-group">
<textarea name="reason"
......@@ -224,8 +237,7 @@
</div>
<button class='btn btn-primary btn-sm pull-right' disabled
id='reserve-submit-button'
type='submit' name='submit'>
<% if (editing) { %>Update<% } else { %>Check<% } %></button>
type='submit' name='submit'>Check</button>
</div>
</div>
</form>
......
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