From 88641ab7c970f8de13a1e00824c58c3018045259 Mon Sep 17 00:00:00 2001 From: Leigh B Stoller Date: Thu, 4 Dec 2014 14:47:03 -0700 Subject: [PATCH] More hacky constraint code to "guide" users to the correct cluster. --- apt/APT_Profile.pm.in | 28 +++++++- apt/create_instance.in | 3 +- www/aptui/instance_defs.php | 9 ++- www/aptui/instantiate.ajax | 11 ++- www/aptui/instantiate.php | 8 +-- www/aptui/js/instantiate.js | 81 ++++++++++++++--------- www/aptui/js/manage_profile.js | 3 +- www/aptui/manage_profile.ajax | 10 ++- www/aptui/manage_profile.php | 9 ++- www/aptui/profile_defs.php | 42 ++++++++++++ www/aptui/template/instantiate-modal.html | 7 +- 11 files changed, 163 insertions(+), 48 deletions(-) diff --git a/apt/APT_Profile.pm.in b/apt/APT_Profile.pm.in index f9985cfda..12527a806 100644 --- a/apt/APT_Profile.pm.in +++ b/apt/APT_Profile.pm.in @@ -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); diff --git a/apt/create_instance.in b/apt/create_instance.in index c35357181..550244159 100755 --- a/apt/create_instance.in +++ b/apt/create_instance.in @@ -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"; diff --git a/www/aptui/instance_defs.php b/www/aptui/instance_defs.php index 0744ca1d4..70190b7d9 100644 --- a/www/aptui/instance_defs.php +++ b/www/aptui/instance_defs.php @@ -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; diff --git a/www/aptui/instantiate.ajax b/www/aptui/instantiate.ajax index 254a563f7..1a5f62fcf 100644 --- a/www/aptui/instantiate.ajax +++ b/www/aptui/instantiate.ajax @@ -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 diff --git a/www/aptui/instantiate.php b/www/aptui/instantiate.php index a80c0d0f3..f822625ac 100755 --- a/www/aptui/instantiate.php +++ b/www/aptui/instantiate.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. # diff --git a/www/aptui/js/instantiate.js b/www/aptui/js/instantiate.js index 8762ea046..15c0cb625 100644 --- a/www/aptui/js/instantiate.js +++ b/www/aptui/js/instantiate.js @@ -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("

" + name + "

"); + $('#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("

" + name + "

"); + $('#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("

" + json.value.name + "

"); - /* * 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); }); diff --git a/www/aptui/js/manage_profile.js b/www/aptui/js/manage_profile.js index 1bdb17374..4ec046612 100644 --- a/www/aptui/js/manage_profile.js +++ b/www/aptui/js/manage_profile.js @@ -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); diff --git a/www/aptui/manage_profile.ajax b/www/aptui/manage_profile.ajax index 58c1734b7..2cbc4ea54 100644 --- a/www/aptui/manage_profile.ajax +++ b/www/aptui/manage_profile.ajax @@ -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. diff --git a/www/aptui/manage_profile.php b/www/aptui/manage_profile.php index 1f01c8f70..a72ff379f 100644 --- a/www/aptui/manage_profile.php +++ b/www/aptui/manage_profile.php @@ -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 "\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 "