Commit e3d2c245 authored by Leigh Stoller's avatar Leigh Stoller

Various changes and fixes for dealing with fully bound rspecs and

multi-site experiments.
parent 288e7bb9
......@@ -979,10 +979,12 @@ sub CheckDatasets($$$)
#
# Set the component_manager_urn for the sites.
#
sub SetSites($$$$)
sub SetSites($$$$$$)
{
my ($prspecstr, $sitemap, $pneedstitcher, $perrmsg) = @_;
my %interface_map = ();
my ($prspecstr, $sitemap, $default_aggregate_urn, $paggregate_urns,
$pneedstitcher, $perrmsg) = @_;
my %interface_map = ();
my %aggregates = ();
my $rspec = GeniXML::Parse($$prspecstr);
if (! defined($rspec)) {
......@@ -991,19 +993,45 @@ sub SetSites($$$$)
}
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $client_id = GetVirtualId($ref);
my $manager_urn = GetManagerId($ref);
my $site_id = GeniXML::GetJacksSiteId($ref);
if (!defined($site_id)) {
$$perrmsg = "No site ID for node $client_id";
return -1;
# A node can be bound in the rspec.
if (defined($manager_urn)) {
if (!GeniHRN::IsValid($manager_urn)) {
$$perrmsg = "$client_id has an invalid manager URN";
return 1;
}
}
my $site_mid = "site:" . $site_id;
if (!exists($sitemap->{$site_mid})) {
$$perrmsg = "No site mapping for node $client_id ($site_id)";
return -1;
# Or there is a site tag, and a site mapping for it.
elsif (defined($site_id)) {
if (defined($sitemap)) {
my $site_mid = "site:" . $site_id;
if (!exists($sitemap->{$site_mid})) {
$$perrmsg =
"No site mapping for node $client_id ($site_id)";
return -1;
}
$manager_urn = $sitemap->{$site_mid};
}
else {
$manager_urn = $default_aggregate_urn;
}
if (!GeniHRN::IsValid($manager_urn)) {
$$perrmsg = "$site_id has an invalid manager URN";
return 1;
}
GeniXML::SetManagerId($ref, $manager_urn);
GeniXML::SetJacksSiteManagerId($ref, $manager_urn);
}
# Else use the default aggregate.
else {
$manager_urn = $default_aggregate_urn;
GeniXML::SetManagerId($ref, $manager_urn);
}
GeniXML::SetManagerId($ref, $sitemap->{$site_mid});
GeniXML::SetJacksSiteManagerId($ref, $sitemap->{$site_mid});
$aggregates{$manager_urn} = $manager_urn;
#
# Get all of the interfaces, we need those for the links, so
......@@ -1012,12 +1040,11 @@ sub SetSites($$$$)
foreach my $iref (GeniXML::FindNodes("n:interface",
$ref)->get_nodelist()) {
my $client_id = GeniXML::GetInterfaceId($iref);
$interface_map{$client_id} = $site_mid;
$interface_map{$client_id} = $manager_urn;
}
}
foreach my $ref (GeniXML::FindNodes("n:link", $rspec)->get_nodelist()) {
my %linksites = ();
my $client_id = GetVirtualId($ref);
foreach my $iref (GeniXML::FindNodes("n:interface_ref",
$ref)->get_nodelist()) {
......@@ -1025,35 +1052,18 @@ sub SetSites($$$$)
next
if (!exists($interface_map{$client_id}));
my $site_mid = $interface_map{$client_id};
GeniXML::AddManagerToLink($ref, $sitemap->{$site_mid})
if (!exists($linksites{$sitemap->{$site_mid}}));
$linksites{$sitemap->{$site_mid}} = 1;
my $manager_urn = $interface_map{$client_id};
GeniXML::AddManagerToLink($ref, $manager_urn)
if (!exists($linksites{$manager_urn}));
$linksites{$manager_urn} = 1;
}
# if more then one site for a link, must use the stitcher.
$$pneedstitcher = 1
if (keys(%linksites) > 1);
}
$$prspecstr = GeniXML::Serialize($rspec);
return 0;
}
#
# Set the component_manager_urn for the rspec
#
sub BindRspec($$$)
{
my ($prspecstr, $aggregate_urn, $perrmsg) = @_;
my $rspec = GeniXML::Parse($$prspecstr);
if (! defined($rspec)) {
$$perrmsg = "Could not parse rspec\n";
return -1;
}
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
GeniXML::SetManagerId($ref, $aggregate_urn);
}
$$prspecstr = GeniXML::Serialize($rspec);
@$paggregate_urns = keys(%aggregates);
return 0;
}
......
......@@ -302,29 +302,36 @@ else {
}
#
# Update rspec with site aggregate urns.
# Sanity check sites
#
if (keys(%{$sitemap})) {
# SetSites will tell us if we must use stitcher.
my $needstitcher = 0;
if (APT_Profile::SetSites(\$rspecstr, $sitemap, \$needstitcher, \$errmsg)) {
fatal($errmsg);
if (defined($sitemap)) {
foreach my $siteid (keys(%{ $sitemap })) {
my $manager_urn = $sitemap->{$siteid};
foreach my $oid (keys(%{ $sitemap })) {
next if
($oid eq $siteid);
if ($manager_urn eq $sitemap->{$oid}) {
UserError("You selected the same cluster for two sites.");
}
}
}
# but do not override command line force.
$usestitcher = 1 if ($needstitcher);
}
elsif (APT_Profile::BindRspec(\$rspecstr, $default_aggregate_urn, \$errmsg)) {
#
# Update rspec with site aggregate urns.
#
# SetSites will tell us if we must use stitcher.
#
my $needstitcher = 0;
if (APT_Profile::SetSites(\$rspecstr, $sitemap, $default_aggregate_urn,
\@aggregate_urns, \$needstitcher, \$errmsg)) {
fatal($errmsg);
}
if (keys(%{$sitemap})) {
foreach my $siteid (keys(%{$sitemap})) {
push(@aggregate_urns, $sitemap->{$siteid})
}
}
else {
push(@aggregate_urns, $default_aggregate_urn);
}
# but do not override command line force.
$usestitcher = 1 if ($needstitcher);
#
# Look for datasets; need to verify that the datasets being referenced
......@@ -1146,7 +1153,7 @@ sub CreateSlivers()
$instance->SetStatus("failed");
$webtask->output($aggobj->webtask()->output())
if (defined($aggobj->webtask()->output()));
$webtask->Exited(1);
$webtask->Exited($code);
return 1;
}
}
......
......@@ -512,25 +512,52 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS
var xml = $(xmlDoc);
var sites = {};
var html = "";
var bound = 0;
var count = 0;
/*
* Find the sites. Might not be any if not a multisite topology
*/
$(xml).find("node").each(function() {
var node_id = $(this).attr("client_id");
var site = this.getElementsByTagNameNS(JACKS_NS, 'site');
if (! site.length) {
return;
var site = this.getElementsByTagNameNS(JACKS_NS, 'site');
var manager = $(this).attr("component_manager_id");
// Keep track of how many bound nodes, of the total.
count++;
if (manager && manager.length) {
var parser = /^urn:publicid:idn\+([\w#!:.]*)\+/i;
var matches = parser.exec(manager);
if (! matches) {
console.error("Could not parse urn: " + manager);
return;
}
// Bound node, no dropdown will be provided for these
// nodes, and if all nodes are bound, no dropdown at all.
bound++;
}
var siteid = $(site).attr("id");
if (siteid === undefined) {
console.log("No site ID in " + site);
return;
else if (site.length) {
var siteid = $(site).attr("id");
if (siteid === undefined) {
console.error("No site ID in " + site);
return;
}
sites[siteid] = siteid;
}
sites[siteid] = siteid;
});
// All nodes bound, no dropdown.
if (count == bound) {
$("#site_selector").addClass("hidden");
$("#nosite_selector").addClass("hidden");
// Clear the form data.
$("#site_selector").html("");
$("#nosite_selector").html("");
return;
}
// If multisite is disabled for the user, or no sites or 1 site.
if (!multisite || Object.keys(sites).length <= 1) {
$("#site_selector").addClass("hidden");
$("#nosite_selector").removeClass("hidden");
......@@ -539,18 +566,19 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS
return;
}
// Create the dropdown selection list. First the options which
// are duplicated in each dropdown.
var options = "";
_.each(amlist, function(name) {
options = options +
"<option value='" + name + "'>" + name + "</option>";
});
var sitenum = 0;
for (var siteid in sites) {
// Create the dropdown selection lists.
_.each(sites, function(siteid) {
var options = "";
_.each(amlist, function(name, key) {
options = options +
"<option value='" + name + "'>" + name + "</option>";
});
html = html +
"<div id='site"+sitenum+"cluster' class='form-horizontal experiment_option'>" +
"<div id='site"+sitenum+"cluster' " +
" class='form-horizontal experiment_option'>" +
" <div class='form-group'>" +
" <label class='col-sm-4 control-label' " +
" style='text-align: right;'>"+
......@@ -562,7 +590,7 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS
" </select>" +
"</div></div></div>";
sitenum++;
}
});
//console.info(html);
$("#nosite_selector").addClass("hidden");
$("#site_selector").removeClass("hidden");
......
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