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 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