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

Various changes and fixes for dealing with fully bound rspecs and

multi-site experiments.
parent 288e7bb9
...@@ -979,10 +979,12 @@ sub CheckDatasets($$$) ...@@ -979,10 +979,12 @@ sub CheckDatasets($$$)
# #
# Set the component_manager_urn for the sites. # Set the component_manager_urn for the sites.
# #
sub SetSites($$$$) sub SetSites($$$$$$)
{ {
my ($prspecstr, $sitemap, $pneedstitcher, $perrmsg) = @_; my ($prspecstr, $sitemap, $default_aggregate_urn, $paggregate_urns,
my %interface_map = (); $pneedstitcher, $perrmsg) = @_;
my %interface_map = ();
my %aggregates = ();
my $rspec = GeniXML::Parse($$prspecstr); my $rspec = GeniXML::Parse($$prspecstr);
if (! defined($rspec)) { if (! defined($rspec)) {
...@@ -991,19 +993,45 @@ sub SetSites($$$$) ...@@ -991,19 +993,45 @@ sub SetSites($$$$)
} }
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) { foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $client_id = GetVirtualId($ref); my $client_id = GetVirtualId($ref);
my $manager_urn = GetManagerId($ref);
my $site_id = GeniXML::GetJacksSiteId($ref); my $site_id = GeniXML::GetJacksSiteId($ref);
if (!defined($site_id)) { # A node can be bound in the rspec.
$$perrmsg = "No site ID for node $client_id"; if (defined($manager_urn)) {
return -1; if (!GeniHRN::IsValid($manager_urn)) {
$$perrmsg = "$client_id has an invalid manager URN";
return 1;
}
} }
my $site_mid = "site:" . $site_id; # Or there is a site tag, and a site mapping for it.
if (!exists($sitemap->{$site_mid})) { elsif (defined($site_id)) {
$$perrmsg = "No site mapping for node $client_id ($site_id)"; if (defined($sitemap)) {
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;
}
$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}); $aggregates{$manager_urn} = $manager_urn;
GeniXML::SetJacksSiteManagerId($ref, $sitemap->{$site_mid});
# #
# Get all of the interfaces, we need those for the links, so # Get all of the interfaces, we need those for the links, so
...@@ -1012,12 +1040,11 @@ sub SetSites($$$$) ...@@ -1012,12 +1040,11 @@ sub SetSites($$$$)
foreach my $iref (GeniXML::FindNodes("n:interface", foreach my $iref (GeniXML::FindNodes("n:interface",
$ref)->get_nodelist()) { $ref)->get_nodelist()) {
my $client_id = GeniXML::GetInterfaceId($iref); 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()) { foreach my $ref (GeniXML::FindNodes("n:link", $rspec)->get_nodelist()) {
my %linksites = (); my %linksites = ();
my $client_id = GetVirtualId($ref);
foreach my $iref (GeniXML::FindNodes("n:interface_ref", foreach my $iref (GeniXML::FindNodes("n:interface_ref",
$ref)->get_nodelist()) { $ref)->get_nodelist()) {
...@@ -1025,35 +1052,18 @@ sub SetSites($$$$) ...@@ -1025,35 +1052,18 @@ sub SetSites($$$$)
next next
if (!exists($interface_map{$client_id})); if (!exists($interface_map{$client_id}));
my $site_mid = $interface_map{$client_id}; my $manager_urn = $interface_map{$client_id};
GeniXML::AddManagerToLink($ref, $sitemap->{$site_mid})
if (!exists($linksites{$sitemap->{$site_mid}})); GeniXML::AddManagerToLink($ref, $manager_urn)
$linksites{$sitemap->{$site_mid}} = 1; if (!exists($linksites{$manager_urn}));
$linksites{$manager_urn} = 1;
} }
# if more then one site for a link, must use the stitcher. # if more then one site for a link, must use the stitcher.
$$pneedstitcher = 1 $$pneedstitcher = 1
if (keys(%linksites) > 1); if (keys(%linksites) > 1);
} }
$$prspecstr = GeniXML::Serialize($rspec); $$prspecstr = GeniXML::Serialize($rspec);
return 0; @$paggregate_urns = keys(%aggregates);
}
#
# 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);
return 0; return 0;
} }
......
...@@ -302,29 +302,36 @@ else { ...@@ -302,29 +302,36 @@ else {
} }
# #
# Update rspec with site aggregate urns. # Sanity check sites
# #
if (keys(%{$sitemap})) { if (defined($sitemap)) {
# SetSites will tell us if we must use stitcher. foreach my $siteid (keys(%{ $sitemap })) {
my $needstitcher = 0; my $manager_urn = $sitemap->{$siteid};
if (APT_Profile::SetSites(\$rspecstr, $sitemap, \$needstitcher, \$errmsg)) { foreach my $oid (keys(%{ $sitemap })) {
fatal($errmsg); 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); fatal($errmsg);
} }
if (keys(%{$sitemap})) { # but do not override command line force.
foreach my $siteid (keys(%{$sitemap})) { $usestitcher = 1 if ($needstitcher);
push(@aggregate_urns, $sitemap->{$siteid})
}
}
else {
push(@aggregate_urns, $default_aggregate_urn);
}
# #
# Look for datasets; need to verify that the datasets being referenced # Look for datasets; need to verify that the datasets being referenced
...@@ -1146,7 +1153,7 @@ sub CreateSlivers() ...@@ -1146,7 +1153,7 @@ sub CreateSlivers()
$instance->SetStatus("failed"); $instance->SetStatus("failed");
$webtask->output($aggobj->webtask()->output()) $webtask->output($aggobj->webtask()->output())
if (defined($aggobj->webtask()->output())); if (defined($aggobj->webtask()->output()));
$webtask->Exited(1); $webtask->Exited($code);
return 1; return 1;
} }
} }
......
...@@ -512,25 +512,52 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS ...@@ -512,25 +512,52 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS
var xml = $(xmlDoc); var xml = $(xmlDoc);
var sites = {}; var sites = {};
var html = ""; var html = "";
var bound = 0;
var count = 0;
/* /*
* Find the sites. Might not be any if not a multisite topology * Find the sites. Might not be any if not a multisite topology
*/ */
$(xml).find("node").each(function() { $(xml).find("node").each(function() {
var node_id = $(this).attr("client_id"); var node_id = $(this).attr("client_id");
var site = this.getElementsByTagNameNS(JACKS_NS, 'site'); var site = this.getElementsByTagNameNS(JACKS_NS, 'site');
var manager = $(this).attr("component_manager_id");
if (! site.length) {
return; // 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"); else if (site.length) {
if (siteid === undefined) { var siteid = $(site).attr("id");
console.log("No site ID in " + site); if (siteid === undefined) {
return; 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) { if (!multisite || Object.keys(sites).length <= 1) {
$("#site_selector").addClass("hidden"); $("#site_selector").addClass("hidden");
$("#nosite_selector").removeClass("hidden"); $("#nosite_selector").removeClass("hidden");
...@@ -539,18 +566,19 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS ...@@ -539,18 +566,19 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS
return; 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; 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 + 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'>" + " <div class='form-group'>" +
" <label class='col-sm-4 control-label' " + " <label class='col-sm-4 control-label' " +
" style='text-align: right;'>"+ " style='text-align: right;'>"+
...@@ -562,7 +590,7 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS ...@@ -562,7 +590,7 @@ function (_, Constraints, sup, ppstart, JacksEditor, aboutaptString, aboutcloudS
" </select>" + " </select>" +
"</div></div></div>"; "</div></div></div>";
sitenum++; sitenum++;
} });
//console.info(html); //console.info(html);
$("#nosite_selector").addClass("hidden"); $("#nosite_selector").addClass("hidden");
$("#site_selector").removeClass("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