Commit 36290a89 authored by Leigh Stoller's avatar Leigh Stoller

More multisite changes; stats and history.

parent 9316dea7
......@@ -453,6 +453,10 @@ sub RecordHistory($)
my ($self) = @_;
my $uuid = $self->uuid();
DBQueryWarn("replace into apt_instance_aggregate_history ".
"select * from apt_instance_aggregates where uuid='$uuid'")
or return -1;
DBQueryWarn("replace into apt_instance_history ".
"select uuid,name,profile_id,profile_version,slice_uuid, ".
" creator,creator_idx,creator_uuid,pid,pid_idx, ".
......@@ -553,6 +557,9 @@ sub ComputeNodeCounts($)
print STDERR "Could not parse manifest for $sliver\n";
return -1;
}
my $pcount = 0;
my $vcount = 0;
foreach my $ref (GeniXML::FindNodes("n:node",
$manifest)->get_nodelist()) {
my $virtualization_type = GeniXML::GetVirtualizationSubtype($ref);
......@@ -565,11 +572,17 @@ sub ComputeNodeCounts($)
if (defined($virtualization_type) &&
$virtualization_type eq "emulab-xen") {
$virtnode_count++;
$vcount++;
next;
}
$physnode_count++;
$pcount++;
}
$sliver->Update({"physnode_count" => $pcount,
"virtnode_count" => $vcount})
== 0 or return -1;
$physnode_count += $pcount;
$virtnode_count += $vcount;
}
$self->Update({"physnode_count" => $physnode_count,
"virtnode_count" => $virtnode_count})
......@@ -731,7 +744,10 @@ sub instance($) { return $_[0]->{'INSTANCE'}; }
sub GenTemp($$)
{
my ($class, $instance) = @_;
my $webtask = WebTask->Create($instance->uuid());
my $webtask = WebTask->LookupByObject($instance->uuid());
if (!defined($webtask)) {
$webtask = WebTask->Create($instance->uuid());
}
$webtask->AutoStore(1);
my $self = {};
......@@ -870,6 +886,31 @@ sub Refresh($)
return 0;
}
#
# Perform some updates ...
#
sub Update($$)
{
my ($self, $argref) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $uuid = $self->uuid();
my $urn = $self->aggregate_urn();
my $query = "update apt_instance_aggregates set ".
join(",", map("$_=" . DBQuoteSpecial($argref->{$_}), keys(%{$argref})));
$query .= " where uuid='$uuid' and aggregate_urn='$urn'";
return -1
if (! DBQueryWarn($query));
return Refresh($self);
}
sub SetStatus($$)
{
my ($self,$status) = @_;
......
......@@ -109,6 +109,10 @@ class Instance
function IsCloud() {
return preg_match('/cloudlab/', $this->servername());
}
function aggregate_name() {
global $urn_mapping;
return $urn_mapping[$this->aggregate_urn()];
}
# Hmm, how does one cause an error in a php constructor?
function IsValid() {
......@@ -469,6 +473,10 @@ class InstanceSliver
function public_url() { return $this->field('public_url'); }
function webtask_id() { return $this->field('webtask_id'); }
function manifest() { return $this->field('manifest'); }
function aggregate_name() {
global $urn_mapping;
return $urn_mapping[$this->aggregate_urn()];
}
# Hmm, how does one cause an error in a php constructor?
function IsValid() {
......
......@@ -15,10 +15,10 @@ function HideModal(which)
function CallServerMethod(url, route, method, args)
{
if (url == null) {
url = 'https://' + window.location.host + '/apt/server-ajax.php';
url = 'server-ajax.php';
}
// ignore url now.
url = 'https://' + window.location.host + '/apt/server-ajax.php';
url = 'server-ajax.php';
if (args == null) {
args = {"noargs" : "noargs"};
}
......@@ -47,6 +47,33 @@ var jacksOutput;
function maketopmap(divname, xml, showinfo, withoutMultiSite)
{
var xmlDoc = $.parseXML(xml);
var xmlXML = $(xmlDoc);
/*
* See how many sites. Do not use multiSite if no sites or
* only one site. Overrides the withoutMultiSite argument if set.
*/
var sites = {};
$(xmlXML).find("node").each(function() {
var JACKS_NS = "http://www.protogeni.net/resources/rspec/ext/jacks/1";
var node_id = $(this).attr("client_id");
var site = this.getElementsByTagNameNS(JACKS_NS, 'site');
if (! site.length) {
return;
}
var siteid = $(site).attr("id");
if (siteid === undefined) {
console.log("No site ID in " + site);
return;
}
sites[siteid] = siteid;
});
if (Object.keys(sites) <= 1) {
withoutMultiSite = true;
}
if (! jacksInstance)
{
jacksInstance = new window.Jacks({
......
......@@ -27,6 +27,7 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
var profile_uuid= null;
var extend = null;
var jacksIDs = {};
var publicURLs = null;
var status_collapsed = false;
var status_message = "";
var statusTemplate = _.template(statusString);
......@@ -169,11 +170,6 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
'&snapuuid=' + uuid);
});
// If we got a publicURL, set the href and show the button.
if (window.APT_OPTIONS.publicURL) {
ShowSliverInfo(window.APT_OPTIONS.publicURL);
}
//
// Attach a hover popover to explain what Clone means. We need
// the hover action delayed by our own code, since we want to
......@@ -362,8 +358,8 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
StatusWatchCallBack.active = 1;
}
// Ditto the publicURL.
if (_.has(json.value, "publicURL")) {
ShowSliverInfo(json.value.publicURL);
if (_.has(json.value, "sliverurls")) {
ShowSliverInfo(json.value.sliverurls);
}
if (status == 'provisioned') {
......@@ -1181,7 +1177,7 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
// Bind a function to start up ssh for one node topologies.
if (nodecount == 1 && !oneonly && dossh) {
startOneSSH = function () {
var nodename = hostportList.keys()[0];
var nodename = Object.keys(hostportList)[0];
var hostport = hostportList[nodename];
NewSSHTab(hostport, nodename);
};
......@@ -1542,10 +1538,51 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
}
}
function ShowSliverInfo(url)
function ShowSliverInfo(urls)
{
$("#sliverinfo_button").attr("href", url);
$("#sliverinfo_button").removeClass("hidden");
if (!publicURLs) {
$('#sliverinfo_dropdown').change(function (event) {
var selected =
$('#sliverinfo_dropdown select option:selected').val();
console.info(selected);
// Find the URL
_.each(publicURLs, function(obj) {
var url = obj.url;
var name = obj.name;
if (name == selected) {
$("#sliverinfo_dropdown a").attr("href", url);
}
});
});
}
publicURLs = urls;
if (urls.length == 0) {
return;
}
if (urls.length == 1) {
$("#sliverinfo_button").attr("href", urls[0].url);
$("#sliverinfo_button").removeClass("hidden");
$("#sliverinfo_dropdown").addClass("hidden");
return;
}
// Selection list.
_.each(urls, function(obj) {
var url = obj.url;
var name = obj.name;
// Add only once of course
var option = $('#sliverinfo_dropdown select option[value="' +
name + '"]');
if (! option.length) {
$("#sliverinfo_dropdown select").append(
"<option value='" + name + "'>" + name + "</option>");
}
});
$("#sliverinfo_button").addClass("hidden");
$("#sliverinfo_dropdown").removeClass("hidden");
}
$(document).ready(initialize);
......
......@@ -73,8 +73,16 @@ if ($all && ISADMIN()) {
" UNIX_TIMESTAMP(s.expires)) as expired, ".
" truncate(a.physnode_count * ".
" ((UNIX_TIMESTAMP(now()) - ".
" UNIX_TIMESTAMP(a.created)) / 3600.0),2) as phours ".
" UNIX_TIMESTAMP(a.created)) / 3600.0),2) as phours, ".
" IFNULL(aggs.count,0) as aggrows, ".
" agg.aggregate_urn as aggrow_urn".
" from apt_instances as a ".
"left join (".
" select uuid, COUNT(*) AS count ".
" from apt_instance_aggregates group by uuid) AS aggs ".
" on aggs.uuid=a.uuid ".
"left join apt_instance_aggregates as agg ".
" on agg.uuid=a.uuid ".
"left join geni.geni_slices as s on ".
" s.uuid=a.slice_uuid ".
"left join geni.geni_users as u on u.uuid=a.creator_uuid ".
......@@ -87,8 +95,16 @@ else {
" UNIX_TIMESTAMP(s.expires)) as expired, ".
" truncate(a.physnode_count * ".
" ((UNIX_TIMESTAMP(now()) - ".
" UNIX_TIMESTAMP(a.created)) / 3600.0),2) as phours ".
" UNIX_TIMESTAMP(a.created)) / 3600.0),2) as phours, ".
" IFNULL(aggs.count,0) as aggrows, ".
" agg.aggregate_urn as aggrow_urn".
" from apt_instances as a ".
"left join (".
" select uuid, COUNT(*) AS count ".
" from apt_instance_aggregates group by uuid) AS aggs ".
" on aggs.uuid=a.uuid ".
"left join apt_instance_aggregates as agg ".
" on agg.uuid=a.uuid ".
"left join geni.geni_slices as s on ".
" s.uuid=a.slice_uuid ".
"left join geni.geni_users as u on u.uuid=a.creator_uuid ".
......@@ -100,8 +116,16 @@ else {
" UNIX_TIMESTAMP(s.expires)) as expired, ".
" truncate(a.physnode_count * ".
" ((UNIX_TIMESTAMP(now()) - ".
" UNIX_TIMESTAMP(a.created)) / 3600.0),2) as phours ".
" UNIX_TIMESTAMP(a.created)) / 3600.0),2) as phours, ".
" IFNULL(aggs.count,0) as aggrows, ".
" agg.aggregate_urn as aggrow_urn".
" from apt_instances as a ".
"left join (".
" select uuid, COUNT(*) AS count ".
" from apt_instance_aggregates group by uuid) AS aggs ".
" on aggs.uuid=a.uuid ".
"left join apt_instance_aggregates as agg ".
" on agg.uuid=a.uuid ".
"left join geni.geni_slices as s on ".
" s.uuid=a.slice_uuid ".
"left join geni.geni_users as u on u.uuid=a.creator_uuid ".
......@@ -152,8 +176,6 @@ function SPITROWS($all, $name, $result)
$profile_name = "$profile_id:$version";
$creator_uid = $row["creator"];
$pid = $row["pid"];
$urn = $row["aggregate_urn"];
$cluster = $urn_mapping[$urn];
$pcount = $row["physnode_count"];
$vcount = $row["virtnode_count"];
$lockdown = $row["admin_lockdown"] || $row["user_lockdown"] ? 1 : 0;
......@@ -182,6 +204,23 @@ function SPITROWS($all, $name, $result)
if (!isset($name)) {
$name = $hrn;
}
#
# If arows non-zero, then we use that for aggregate_urn,
# and if its more then 1, we need to consume the extras rows
# to get the rest of the aggregate urns.
#
if ($row["aggrows"] > 0) {
$cluster = $urn_mapping[$row["aggrow_urn"]];
for ($i = 1; $i < $row["aggrows"]; $i++) {
$row = mysql_fetch_array($result);
$cluster .= "," . $urn_mapping[$row["aggrow_urn"]];
}
}
else {
$cluster = $urn_mapping[$row["aggregate_urn"]];
}
echo " <tr>\n";
echo "<td><a href='status.php?uuid=$uuid'>$name</a></td>";
if ($profile) {
......
......@@ -118,8 +118,8 @@ function Do_GetInstanceStatus()
}
}
if ($sliver->public_url()) {
$blob["sliverurls"][$sliver->aggregate_urn()] =
$sliver->public_url();
$blob["sliverurls"][] = array("name" => $sliver->aggregate_name(),
"url" => $sliver->public_url());
}
}
$blob["havemanifests"] = $havemanifests;
......@@ -509,15 +509,18 @@ function Do_ConsoleURL()
global $instance, $creator;
global $ajax_args;
if (StatusSetupAjax(1)) {
return;
}
if (!isset($this_user)) {
SPITAJAX_ERROR(1, "Only registered users can reboot/reload nodes");
return;
}
if (!isset($ajax_args["node"])) {
SPITAJAX_ERROR(1, "Missing node argument");
return 1;
}
$node = $ajax_args["node"];
if (StatusSetupAjax(1)) {
return;
}
$uuid = $instance->uuid();
$slice = GeniSlice::Lookup("sa", $instance->slice_uuid());
if (!slice) {
......@@ -556,21 +559,19 @@ function Do_ConsoleURL()
#
function Do_Snapshot()
{
global $this_user;
global $this_user, $instance;
global $ajax_args;
$this_idx = $this_user->uid_idx();
if (!isset($ajax_args["uuid"])) {
SPITAJAX_ERROR(1, "Missing profile uuid");
if (StatusSetupAjax(1)) {
return;
}
$uuid = $ajax_args["uuid"];
$instance = Instance::Lookup($uuid);
if (!$instance) {
SPITAJAX_ERROR(1, "Unknown instance uuid");
if (!isset($this_user)) {
SPITAJAX_ERROR(1, "Only registered users can snapshot nodes");
return;
}
$this_idx = $this_user->uid_idx();
$uuid = $ajax_args["uuid"];
if ($this_idx != $instance->creator_idx() && !ISADMIN()) {
SPITAJAX_ERROR(1, "Not enough permission. Maybe Clone instead?");
return;
......@@ -650,20 +651,18 @@ function Do_Snapshot()
#
function Do_SnapshotStatus()
{
global $this_user;
global $this_user, $instance;
global $ajax_args;
$this_idx = $this_user->uid_idx();
if (!isset($ajax_args["uuid"])) {
SPITAJAX_ERROR(1, "Missing profile uuid");
if (StatusSetupAjax(1)) {
return;
}
$instance = Instance::Lookup($ajax_args["uuid"]);
if (!$instance) {
SPITAJAX_ERROR(1, "Unknown instance uuid");
if (!isset($this_user)) {
SPITAJAX_ERROR(1, "Only registered users can snapshot nodes");
return;
}
$this_idx = $this_user->uid_idx();
if ($this_idx != $instance->creator_idx() && !ISADMIN()) {
SPITAJAX_ERROR(1, "Not enough permission");
return;
......@@ -704,21 +703,17 @@ function Do_SnapshotStatus()
#
function Do_Refresh()
{
global $this_user;
global $this_user, $instance;
global $ajax_args;
$this_idx = $this_user->uid_idx();
if (!isset($ajax_args["uuid"])) {
SPITAJAX_ERROR(1, "Missing profile uuid");
#
# Guest users can do this.
#
if (StatusSetupAjax(1)) {
return;
}
$this_idx = $this_user->uid_idx();
$uuid = $ajax_args["uuid"];
$instance = Instance::Lookup($uuid);
if (!$instance) {
SPITAJAX_ERROR(1, "Unknown instance uuid");
return;
}
if ($this_idx != $instance->creator_idx() && !ISADMIN()) {
SPITAJAX_ERROR(1, "Not enough permission. Maybe Clone instead?");
return;
......@@ -727,7 +722,7 @@ function Do_Refresh()
# Call out to the backend.
#
$webtask_id = WebTask::GenerateID();
$retval = SUEXEC($this_user->uid(), "nobody",
$retval = SUEXEC("nobody", "nobody",
"webmanage_instance -t $webtask_id -- refresh $uuid",
SUEXEC_ACTION_IGNORE);
$webtask = WebTask::Lookup($webtask_id);
......@@ -757,14 +752,18 @@ function Do_Refresh()
#
function Do_RebootOrReload($which)
{
global $this_user;
global $this_user, $instance;
global $ajax_args;
if (StatusSetupAjax(1)) {
return;
}
if (!isset($this_user)) {
SPITAJAX_ERROR(1, "Only registered users can reboot/reload nodes");
return;
}
$this_idx = $this_user->uid_idx();
$uuid = $ajax_args["uuid"];
if (!isset($ajax_args["node_id"])) {
SPITAJAX_ERROR(1, "Missing node_id");
......@@ -774,17 +773,6 @@ function Do_RebootOrReload($which)
if (!preg_match("/^[-\w]+$/", $node_id)) {
SPITAJAX_ERROR(1, "Illegal characters in node_id");
}
if (!isset($ajax_args["uuid"])) {
SPITAJAX_ERROR(1, "Missing profile uuid");
return;
}
$uuid = $ajax_args["uuid"];
$instance = Instance::Lookup($uuid);
if (!$instance) {
SPITAJAX_ERROR(1, "Unknown instance uuid");
return;
}
if ($this_idx != $instance->creator_idx() && !ISADMIN()) {
SPITAJAX_ERROR(1, "Not enough permission. Maybe Clone instead?");
return;
......@@ -843,6 +831,10 @@ function Do_Lockout()
global $this_user;
global $ajax_args;
if (!isset($this_user) || !ISADMIN()) {
SPITAJAX_ERROR(1, "Not enough permission.");
return;
}
$this_idx = $this_user->uid_idx();
if (!isset($ajax_args["uuid"])) {
......@@ -859,10 +851,6 @@ function Do_Lockout()
SPITAJAX_ERROR(1, "Unknown instance uuid");
return;
}
if (!ISADMIN()) {
SPITAJAX_ERROR(1, "Not enough permission.");
return;
}
$lockout = ($ajax_args["lockout"] ? 1 : 0);
if (!DBQueryWarn("update apt_instances set extension_adminonly='$lockout' ".
"where uuid='$uuid'")) {
......
......@@ -74,8 +74,18 @@
style='margin-right: 10px;'
id='sliverinfo_button'
href='#'
type='button'>Sliver
</a>
target='_blank'
type='button'>Sliver</a>
<div id='sliverinfo_dropdown' class='hidden'>
<select style='margin-right: 0px;'>
<option value='selectme'>Slivers</option>
</select>
<a class='btn btn-info btn-tiny'
style='margin-right: 10px;'
href='#'
target='_blank'
type='button'>Go</a>
</div>
</div>
<% if (isadmin) { %>
<div class='pull-left'
......
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