Commit 88641ab7 authored by Leigh Stoller's avatar Leigh Stoller

More hacky constraint code to "guide" users to the correct cluster.

parent 36b9e4a6
......@@ -762,7 +762,7 @@ sub ConvertDiskImages($)
}
# Total nonsense, to be thrown away.
sub CheckImageConstraints($$$)
sub CheckNodeConstraints($$$)
{
my ($self, $iscloudlab, $pmsg) = @_;
my $cloudwww = "www.utah.cloudlab.us";
......@@ -775,12 +775,36 @@ sub CheckImageConstraints($$$)
}
foreach my $ref (GeniXML::FindNodes("n:node", $rspec)->get_nodelist()) {
my $client_id = GetVirtualId($ref);
my $virtualization_type = GeniXML::GetVirtualizationSubtype($ref);
if (defined($virtualization_type) && $iscloudlab &&
$virtualization_type eq "emulab-xen") {
$$pmsg = "Node '$client_id' is a XEN VM, which is ".
"not supported on the Cloudlab cluster";
return -1;
}
my $diskref = GeniXML::GetDiskImage($ref);
next
if (!defined($diskref));
my $image_url = GeniXML::GetText("url", $diskref);
my $image_urn = GeniXML::GetText("name", $diskref);
next
if (!defined($image_url));
if (!(defined($image_url) || defined($image_urn)));
if (defined($image_urn)) {
if ($iscloudlab && $image_urn !~ /ARM/) {
$$pmsg = "Node '$client_id' disk_image will not run ".
"on the Cloudlab cluster";
return -1;
}
elsif (!$iscloudlab && $image_urn =~ /ARM/) {
$$pmsg = "Node '$client_id' disk_image will only run ".
"on the Cloudlab cluster";
return -1;
}
}
next if
(!defined($image_url));
# Get the hostname for the image URL.
my $uri = URI->new($image_url);
......
......@@ -311,7 +311,7 @@ if (APT_Profile::CheckDatasets($rspecstr, $profile_object->pid(), \$errmsg)) {
my $iscloudlab =
($CMURN eq "urn:publicid:IDN+utah.cloudlab.us+authority+cm" ? 1 : 0);
if ($profile_object->CheckImageConstraints($iscloudlab, \$errmsg)) {
if ($profile_object->CheckNodeConstraints($iscloudlab, \$errmsg)) {
UserError($errmsg);
}
......@@ -522,6 +522,7 @@ print STDERR "Email: $user_email" . (!$localuser ? " (guest)" : "") . "\n";
print STDERR "Profile: " . $profile_object->name() . ":${version}\n";
print STDERR "Slice: $slice_urn\n";
print STDERR "Server: $SERVER_NAME\n";
print STDERR "Cluster: $CMURN\n";
print STDERR "\n";
print STDERR "$rspecstr\n";
......
......@@ -24,7 +24,7 @@
#
$am_array = array('Utah APT' =>
"urn:publicid:IDN+apt.emulab.net+authority+cm",
"urn:publicid:IDN+apt.emulab.net+authority+cm",
'Utah Cloudlab' =>
"urn:publicid:IDN+utah.cloudlab.us+authority+cm",
'Utah DDC' =>
......@@ -32,6 +32,13 @@ $am_array = array('Utah APT' =>
'Utah PG' =>
"urn:publicid:IDN+emulab.net+authority+cm");
if ($ISCLOUD) {
$DEFAULT_AGGREGATE = "Utah Cloudlab";
}
else {
$DEFAULT_AGGREGATE = "Utah APT";
}
class Instance
{
var $instance;
......
......@@ -25,6 +25,7 @@ chdir("..");
include_once("webtask.php");
chdir("apt");
include_once("profile_defs.php");
include_once("instance_defs.php");
#
# Return info about specific profile.
......@@ -33,6 +34,7 @@ function Do_GetProfile()
{
global $this_user;
global $ajax_args;
global $DEFAULT_AGGREGATE;
if (!isset($ajax_args["uuid"])) {
SPITAJAX_ERROR(1, "Missing profile uuid");
......@@ -48,12 +50,19 @@ function Do_GetProfile()
SPITAJAX_ERROR(1, "No such profile $uuid");
return;
}
$amdefault = $DEFAULT_AGGREGATE;
# Temporary override until constraint system in place.
if ($profile->BestAggregate()) {
$amdefault = $profile->BestAggregate();
}
#
# Knowing the UUID means the user can instantiate it,
# so no permission checks on the profile.
#
SPITAJAX_RESPONSE(array('rspec' => $profile->rspec(),
'name' => $profile->name()));
'name' => $profile->name(),
'amdefault' => $amdefault));
}
# Local Variables:
# mode:php
......
......@@ -469,12 +469,8 @@ if (!isset($create)) {
$defaults["email"] = "";
$defaults["sshkey"] = "";
$defaults["profile"] = (isset($profile) ? $profile : $profile_default);
if ($ISCLOUD) {
$defaults["where"] = 'Utah APT';
}
else {
$defaults["where"] = 'Utah APT';
}
$defaults["where"] = $DEFAULT_AGGREGATE;
#
# Look for current user or cookie that tells us who the user is.
#
......
......@@ -8,6 +8,7 @@ function (_, sup, aboutaptString, aboutcloudString)
'use strict';
var ajaxurl;
var amdefault;
function initialize()
{
......@@ -29,7 +30,7 @@ function (_, sup, aboutaptString, aboutcloudString)
$('#verify_modal').modal('show');
}
$('#quickvm_topomodal').on('shown.bs.modal', function() {
ShowProfileList($('.current'))
ShowProfileSelection($('.current'))
});
$('button#reset-form').click(function (event) {
......@@ -42,12 +43,11 @@ function (_, sup, aboutaptString, aboutcloudString)
});
$('li.profile-item').click(function (event) {
event.preventDefault();
ShowProfileList(event.target);
ShowProfileSelection(event.target);
});
$('button#showtopo_select').click(function (event) {
event.preventDefault();
UpdateProfileSelection($('.selected'));
ShowProfileList($('.selected'));
ChangeProfileSelection($('.selected'));
$('#quickvm_topomodal').modal('hide');
});
$('#instantiate_submit').click(function (event) {
......@@ -55,52 +55,72 @@ function (_, sup, aboutaptString, aboutcloudString)
return true;
});
var startProfile = $('#profile_name li[value = ' + window.PROFILE + ']')
UpdateProfileSelection(startProfile);
ShowProfileList(startProfile, true);
ChangeProfileSelection(startProfile);
_.delay(function () {$('.dropdown-toggle').dropdown();}, 500);
}
function resetForm($form) {
$form.find('input:text, input:password, select, textarea').val('');
}
function UpdateProfileSelection(selectedElement)
{
var profile_name = $(selectedElement).text();
var profile_value = $(selectedElement).attr('value');
$('#selected_profile').attr('value', profile_value);
$('#selected_profile_text').html("" + profile_name);
if (!$(selectedElement).hasClass('current')) {
function ShowProfileSelection(selectedElement) {
if (!$(selectedElement).hasClass('selected')) {
$('#profile_name li').each(function() {
$(this).removeClass('current');
$(this).removeClass('selected');
});
$(selectedElement).addClass('current');
$(selectedElement).addClass('selected');
}
var continuation = function(rspec, description, name, amdefault) {
$('#showtopo_title').html("<h3>" + name + "</h3>");
$('#showtopo_description').html(description);
sup.maketopmap('#showtopo_div', rspec, null);
};
GetProfile($(selectedElement).attr('value'), continuation);
}
function ShowProfileList(selectedElement, justTitle)
{
var profile = $(selectedElement).attr('value');
if (!$(selectedElement).hasClass('selected')) {
function ChangeProfileSelection(selectedElement) {
if (!$(selectedElement).hasClass('current')) {
$('#profile_name li').each(function() {
$(this).removeClass('selected');
$(this).removeClass('current');
});
$(selectedElement).addClass('selected');
$(selectedElement).addClass('current');
}
var profile_name = $(selectedElement).text();
var profile_value = $(selectedElement).attr('value');
$('#selected_profile').attr('value', profile_value);
$('#selected_profile_text').html("" + profile_name);
var continuation = function(rspec, description, name, amdefault) {
$('#showtopo_title').html("<h3>" + name + "</h3>");
$('#showtopo_description').html(description);
$('#selected_profile_description').html(description);
// Set the default aggregate.
if ($('#profile_where').length) {
// Deselect current option.
$('#profile_where option').prop("selected", false);
// Find and select new option.
$('#profile_where option')
.filter('[value="'+ amdefault + '"]')
.prop('selected', true);
}
};
GetProfile($(selectedElement).attr('value'), continuation);
}
function GetProfile(profile, continuation) {
var callback = function(json) {
if (json.code) {
alert("Could not get profile: " + json.value);
return;
}
console.info(json);
var xmlDoc = $.parseXML(json.value.rspec);
var xml = $(xmlDoc);
$('#showtopo_title').html("<h3>" + json.value.name + "</h3>");
/*
* We now use the desciption from inside the rspec, unless there
* is none, in which case look to see if the we got one in the
......@@ -117,18 +137,13 @@ function (_, sup, aboutaptString, aboutcloudString)
if (!description || description == "") {
description = "Hmm, no description for this profile";
}
$('#showtopo_description').html(description);
$('#selected_profile_description').html(description);
if (! justTitle) {
sup.maketopmap('#showtopo_div', json.value.rspec, null);
}
continuation(json.value.rspec, description,
json.value.name, json.value.amdefault);
}
var $xmlthing = sup.CallServerMethod(ajaxurl,
"instantiate", "GetProfile",
{"uuid" : profile});
$xmlthing.done(callback);
}
$(document).ready(initialize);
});
......@@ -106,7 +106,8 @@ function (_, sup, filesize, JacksEditor, ShowImagingModal, moment,
var guest_html = guestInstTemplate({});
$('#guest_div').html(guest_html);
$('#publish_div').html(publishString);
var instantiate_html = InstTemplate({ amlist: amlist });
var instantiate_html = InstTemplate({ amlist: amlist,
amdefault: window.AMDEFAULT});
$('#instantiate_div').html(instantiate_html);
var rspectext_html = rspectextTemplate({});
$('#rspectext_div').html(rspectext_html);
......
......@@ -286,7 +286,7 @@ function Do_GuestInstantiate()
#
function Do_Instantiate()
{
global $this_user, $am_array;
global $this_user, $am_array, $DEFAULT_AGGREGATE;
global $ajax_args;
$this_idx = $this_user->uid_idx();
......@@ -321,6 +321,14 @@ function Do_Instantiate()
return;
}
}
else {
# Temporary until constraint system in place.
$best = $profile->BestAggregate();
if (!$best) {
$best = $DEFAULT_AGGREGATE;
}
$opts = "-a " . $am_array[$best];
}
#
# Invoke the backend.
......
......@@ -56,7 +56,7 @@ $optargs = OptionalPageArguments("create", PAGEARG_STRING,
#
function SPITFORM($formfields, $errors)
{
global $this_user, $projlist, $action, $profile;
global $this_user, $projlist, $action, $profile, $DEFAULT_AGGREGATE;
global $notifyupdate, $notifyclone, $snapuuid, $am_array;
$viewing = 0;
$candelete = 0;
......@@ -104,10 +104,16 @@ function SPITFORM($formfields, $errors)
echo "</script>\n";
$amlist = array();
$amdefault = "";
if ($viewing && (ISADMIN() || STUDLY())) {
while (list($am) = each($am_array)) {
$amlist[] = $am;
}
$amdefault = $DEFAULT_AGGREGATE;
# Temporary override until constraint system in place.
if ($profile->BestAggregate()) {
$amdefault = $profile->BestAggregate();
}
}
echo "<script type='text/plain' id='amlist-json'>\n";
echo htmlentities(json_encode($amlist));
......@@ -150,6 +156,7 @@ function SPITFORM($formfields, $errors)
echo " window.HISTORY = $history;\n";
echo " window.ACTIVITY = $activity;\n";
echo " window.TITLE = '$title';\n";
echo " window.AMDEFAULT= '$amdefault';\n";
echo " window.BUTTONLABEL = '$button_label';\n";
if (isset($snapuuid)) {
echo " window.SNAPUUID = '$snapuuid';\n";
......
......@@ -389,5 +389,47 @@ class Profile
function CanView($user) {
return $this->CanInstantiate($user);
}
function BestAggregate() {
$parsed_xml = simplexml_load_string($this->rspec());
foreach ($parsed_xml->node as $node) {
# No XEN VMs on Cloudlab yet.
if ($node->sliver_type &&
$node->sliver_type["name"] &&
$node->sliver_type["name"] == "emulab-xen") {
return "Utah APT";
}
# Check URL
if (! ($node->sliver_type &&
$node->sliver_type->disk_image &&
($node->sliver_type->disk_image["url"] ||
$node->sliver_type->disk_image["name"]))) {
continue;
}
if ($node->sliver_type->disk_image["name"]) {
$name = $node->sliver_type->disk_image["name"];
#
# The only image that runs on Cloudlab is UBUNTU14-64-ARM
#
if (preg_match("/ARM/", $name)) {
return "Utah Cloudlab";
}
return "Utah APT";
}
else {
$url = $node->sliver_type->disk_image["url"];
if (preg_match("/utah\.cloudlab\.us/", $url)) {
return "Utah Cloudlab";
}
if (preg_match("/emulab\.net/", $url) ||
preg_match("/geniracks\.net/", $url) ||
preg_match("/instageni/", $url)) {
return "Utah APT";
}
}
}
return null;
}
}
?>
......@@ -9,7 +9,12 @@
Please select an AM<br>
<select id='instantiate_where'>
<% _.each(amlist, function(name) { %>
<option value='<%= name %>'><%= name %></option>
<option
<% if (name == amdefault) { %>
selected
<% } %>
value='<%= name %>'><%= name %>
</option>
<% }); %>
</select>
<br><br>
......
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