Commit cd6a4cb4 authored by Leigh Stoller's avatar Leigh Stoller

First cut at auto approving experiments that would otherwise require

admin approval. Informational for now, the results are ignores and
stored in the DB and shown on the admin extend page.
parent d9b96847
......@@ -72,6 +72,7 @@ my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $GENEXTENDCRED = "$TB/sbin/protogeni/genextendcred";
my $GENIUSER = "geniuser";
my $MAINSITE = @TBMAINSITE@;
# Cache of instances to avoid regenerating them.
my %instances = ();
......@@ -784,7 +785,8 @@ sub ComputeNodeCounts($)
$manager_urn ne $sliver->aggregate_urn());
if (defined($virtualization_type) &&
$virtualization_type eq "emulab-xen") {
($virtualization_type eq "emulab-xen" ||
$virtualization_type eq "emulab-blockstore")) {
$vcount++;
next;
}
......@@ -803,6 +805,66 @@ sub ComputeNodeCounts($)
return 0;
}
#
# Go through all the manifests and return a list of nodes.
#
sub GetNodeDetails($)
{
my ($self) = @_;
my $rval = {};
my @slivers = $self->AggregateList();
if (!@slivers) {
print STDERR "No slivers for $self\n";
return undef;
}
foreach my $sliver (@slivers) {
my $manifest = GeniXML::Parse($sliver->manifest());
if (! defined($manifest)) {
print STDERR "Could not parse manifest for $sliver\n";
return undef;
}
my $nodes = {};
foreach my $ref (GeniXML::FindNodes("n:node",
$manifest)->get_nodelist(),
GeniXML::FindNodesNS("n:vhost",
$manifest,
$GeniXML::EMULAB_NS)->get_nodelist()) {
my $virtualization_type = GeniXML::GetVirtualizationSubtype($ref);
my $manager_urn = GetManagerId($ref);
my $isvnode = 0;
# Combined rspec.
next
if (!defined($manager_urn) ||
$manager_urn ne $sliver->aggregate_urn());
if (defined($virtualization_type) &&
($virtualization_type eq "emulab-xen" ||
$virtualization_type eq "emulab-blockstore")) {
$isvnode = 1;
}
my $client_id = GetVirtualId($ref);
my $node_id = GetVnodeId($ref);
if (GeniHRN::IsValid($node_id)) {
my $hrn = GeniHRN->new($node_id);
if (!$hrn->IsNode()) {
print STDERR "$node_id is not a node\n";
return undef;
}
$node_id = $hrn->id();
}
$nodes->{$node_id} = {
"client_id" => $client_id,
"isvirtnode" => $isvnode,
};
}
$rval->{$sliver->aggregate_urn()} = $nodes;
}
return $rval;
}
#
# Add an aggregate to an instance.
#
......
This diff is collapsed.
......@@ -395,6 +395,7 @@ sub IsCM($) { return ($_[0]->IsAuthority() &&
sub IsRoot($) { return ($_[0]->IsAuthority() &&
$_[0]->id() =~ /^root$/i ? 1 : 0); }
sub IsUser($) { return $_[0]->type() =~ /^user$/i ? 1 : 0; }
sub IsNode($) { return $_[0]->type() =~ /^node$/i ? 1 : 0; }
#
# Image accessors. If we use any of these we want to parse the urn
......
......@@ -929,8 +929,13 @@ class ExtensionInfo
function wanted() { return $this->field('wanted'); }
function granted() { return $this->field('granted'); }
function admin() { return $this->field('admin'); }
function needapproval() { return $this->field('needapproval'); }
function reason() { return $this->field('reason'); }
function message() { return $this->field('message'); }
function autoapproved() { return $this->field('autoapproved'); }
function autoapproved_reason() {
return $this->field('autoapproved_reason');
}
# Hmm, how does one cause an error in a php constructor?
function IsValid() {
......
......@@ -69,6 +69,16 @@ $(function ()
$("#extension-reason-row pre").text($('#extension-reason').text());
$("#extension-reason-row").removeClass("hidden");
}
// This activates the popover subsystem.
$('#history-panel-content [data-toggle="popover"]').popover({
trigger: 'hover',
placement: 'auto',
});
// Extension metrics handler, to show in modal
$('#history-panel-content .autoapprove-metrics').click(function (e) {
e.preventDefault();
ShowMetricsModal(this);
});
// Default number of days.
if (window.DAYS) {
......@@ -408,6 +418,17 @@ $(function ()
"notes" : notes});
xmlthing.done(callback);
}
function ShowMetricsModal(target)
{
var idx = $(target).data("idx");
var str = extensions[idx].autoapproved_metrics;
str.replace(/\\"/g, '"');
var obj = JSON.parse(str);
str = JSON.stringify(obj, null, 2);
console.info(str);
$('#metrics-content').text(str);
sup.ShowModal('#metrics-modal');
}
// Helper.
function decodejson(id) {
......
......@@ -5,6 +5,7 @@
<th>Action</th>
<th>Wanted</th>
<th>Granted</th>
<th>AutoApproved</th>
</tr>
</thead>
<tbody>
......@@ -18,13 +19,29 @@
<% if (extension.action == "request") { %>
<td><%- extension.wanted %></td>
<td><%- extension.granted %></td>
<td>
<% if (extension.autoapproved == "1") { %>
Yes
<% } else if (extension.autoapproved_reason) { %>
<span style="text-decoration: underline;"
data-toggle='popover'
data-delay='{"hide":100, "show":250}'
data-content='<%- extension.autoapproved_reason %>'
data-html='true'>Denied</span>
<% } %>
<% if (extension.autoapproved_metrics) { %>
(<a href='#'
data-idx="<%- extension.idx %>"
class="autoapprove-metrics">metrics</a>)
<% } %>
</td>
<% } else { %>
<td>n/a</td>
<td>n/a</td>
<% } %>
</tr>
<tr>
<td colspan="3"><pre class="history-reason"><%- extension.reason %></pre>
<td colspan="4"><pre class="history-reason"><%- extension.reason %></pre>
</td>
</tr>
<% }); %>
......
......@@ -337,3 +337,21 @@ pre {
</div>
</div>
</div>
<div id='metrics-modal' class='modal fade'>
<div class='modal-dialog'>
<div class='modal-content'>
<div class='modal-body'>
<button type='button' class='close' data-dismiss='modal'
aria-hidden='true'>&times;</button>
<div class='clearfix'></div>
<div class='panel panel-default'>
<div class='panel-body'>
<div class="scrollable-panel">
<pre id="metrics-content"></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
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