From 32f5b81ffc15c50c18acb7a7f53c77fea5abb6c0 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 2 Jul 2012 14:28:35 +0200 Subject: [PATCH] Sunstone (#1314): Enable volatile disks hotplugging, improve quotas representation (cherry picked from commit fad8616147b0bca1adb10a90ead14d6b0d5e3fa0) --- src/sunstone/public/js/plugins/groups-tab.js | 30 ++++----- src/sunstone/public/js/plugins/users-tab.js | 65 +++++++++++--------- src/sunstone/public/js/plugins/vms-tab.js | 38 ++++++++++-- src/sunstone/public/js/sunstone-util.js | 26 ++++---- 4 files changed, 94 insertions(+), 65 deletions(-) diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index ea4319232d..2daae71f36 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -105,21 +105,15 @@ var group_quotas_tmpl = '
\ \
\
\ -
'+tr("Current quotas")+':
\
\ -
\ -
    \ -
\ -
\ -
    \ -
\ -
\ -
    \ -
\ -
\ -
    \ -
\ -
\ + \ + \ + \ + \ + \ + \ + \ +
'+tr("Type")+''+tr("Quota")+''+tr("Edit")+'
\
\ \
\ @@ -192,10 +186,10 @@ var group_actions = { call: OpenNebula.Group.show, callback: function (request,response) { var parsed = parseQuotas(response.GROUP); - $('ul#quotas_ul_vm',$group_quotas_dialog).html(parsed.VM) - $('ul#quotas_ul_datastore',$group_quotas_dialog).html(parsed.DATASTORE) - $('ul#quotas_ul_image',$group_quotas_dialog).html(parsed.IMAGE) - $('ul#quotas_ul_network',$group_quotas_dialog).html(parsed.NETWORK) + $('.current_quotas table tbody',$group_quotas_dialog).append(parsed.VM); + $('.current_quotas table tbody',$group_quotas_dialog).append(parsed.DATASTORE); + $('.current_quotas table tbody',$group_quotas_dialog).append(parsed.IMAGE); + $('.current_quotas table tbody',$group_quotas_dialog).append(parsed.NETWORK); }, error: onError }, diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 0fe79025c2..d894c98f48 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -146,20 +146,15 @@ var user_quotas_tmpl = '\ \
\
\ -
'+tr("Current quotas")+':
\
\ -
\ -
    \ -
\ -
\ -
    \ -
\ -
\ -
    \ -
\ -
\ -
    \ -
\ + \ + \ + \ + \ + \ + \ + \ +
'+tr("Type")+''+tr("Quota")+''+tr("Edit")+'
\
\
\ \ @@ -329,10 +324,10 @@ var user_actions = { // quota objects with html code (
  • ) that can be inserted // in the dialog var parsed = parseQuotas(response.USER); - $('ul#quotas_ul_vm',$user_quotas_dialog).html(parsed.VM) - $('ul#quotas_ul_datastore',$user_quotas_dialog).html(parsed.DATASTORE) - $('ul#quotas_ul_image',$user_quotas_dialog).html(parsed.IMAGE) - $('ul#quotas_ul_network',$user_quotas_dialog).html(parsed.NETWORK) + $('.current_quotas table tbody',$user_quotas_dialog).append(parsed.VM); + $('.current_quotas table tbody',$user_quotas_dialog).append(parsed.DATASTORE); + $('.current_quotas table tbody',$user_quotas_dialog).append(parsed.IMAGE); + $('.current_quotas table tbody',$user_quotas_dialog).append(parsed.NETWORK); }, error: onError }, @@ -597,21 +592,31 @@ function updateUserInfo(request,user){ '' }; + var quotas_tab_html = ''; + + if (!$.isEmptyObject(user_info.VM_QUOTA)) + quotas_tab_html += '\ + '+prettyPrintJSON(user_info.VM_QUOTA)+'\ +
    ' + + if (!$.isEmptyObject(user_info.DATASTORE_QUOTA)) + quotas_tab_html += '\ + '+prettyPrintJSON(user_info.DATASTORE_QUOTA)+'\ +
    ' + + if (!$.isEmptyObject(user_info.IMAGE_QUOTA)) + quotas_tab_html += '\ + '+prettyPrintJSON(user_info.IMAGE_QUOTA)+'\ +
    '; + + if (!$.isEmptyObject(user_info.NETWORK_QUOTA)) + quotas_tab_html += '\ + '+prettyPrintJSON(user_info.NETWORK_QUOTA)+'\ +
    '; + var quotas_tab = { title : tr("User quotas"), - content : '\ - \ - '+prettyPrintJSON(user_info.DATASTORE_QUOTA)+'\ -
    \ - \ - '+prettyPrintJSON(user_info.VM_QUOTA)+'\ -
    \ - \ - '+prettyPrintJSON(user_info.IMAGE_QUOTA)+'\ -
    \ - \ - '+prettyPrintJSON(user_info.NETWORK_QUOTA)+'\ -
    ' + content : quotas_tab_html }; Sunstone.updateInfoPanelTab("user_info_panel","user_info_tab",info_tab); diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 053d6de235..1e52062d3f 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -651,8 +651,20 @@ var vms_tab = { SunstoneMonitoringConfig['VM'] = { plot: function(monitoring){ + // we have the monitoring information and we need to + // send it somewhere to be plotted + + // Write total VMs $('#totalVMs', $dashboard).text(monitoring['totalVMs']) + // Calculate bandwidth + // netUsage object is global variable and stores last values of + // BU, BD and the time they were stored. + // According to the current values and time, we can calculate + // how much bandwith we are using. + // Once done, we update the netUsage object with the new values + // for the next time. + var t = ((new Date().getTime()) - netUsage.time) / 1000 //in secs var bandwidth_up = monitoring['netUsageBar'][1].data[0][0] - netUsage.up bandwidth_up /= t @@ -672,6 +684,7 @@ SunstoneMonitoringConfig['VM'] = { //if (!$dashboard.is(':visible')) return; + // plot these two graphs var container = $('div#vmStatePie',$dashboard); SunstoneMonitoring.plot('VM', 'statePie', @@ -717,6 +730,7 @@ SunstoneMonitoringConfig['VM'] = { } }, "netUsageBar" : { + // Show in a single var the values from netrx and nettx paths: [ "NET_RX", "NET_TX" ], operation: SunstoneMonitoring.ops.singleBar, plotOptions: { @@ -762,6 +776,8 @@ function str_start_time(vm){ return pretty_time(vm.STIME); }; + +// Return the IP or several IPs of a VM function ip_str(vm){ var nic = vm.TEMPLATE.NIC; var ip = '--'; @@ -850,6 +866,10 @@ function updateVMachinesView(request, vmachine_list){ updateVResDashboard("vms",vmachine_list); }; + +// Returns the html code for a nice formatted VM history +// Some calculations are performed, inspired from what is done +// in the CLI function generateHistoryTable(vm){ var html = ' \ \ @@ -1064,7 +1084,9 @@ function updateVMInfo(request,vm){ $('tr.at_image',$hotplugging_tab).show(); } -//Generates the HTML for the hotplugging tab +// Generates the HTML for the hotplugging tab +// This is a list of disks with the save_as, detach options. +// And a form to attach a new disk to the VM, if it is running. function printDisks(vm_info){ var im_sel = makeSelectOptions(dataTable_images, 1, //id col - trick -> reference by name! @@ -1102,20 +1124,25 @@ function printDisks(vm_info){ html += disk.DISK_ID + ' - ' + (disk.IMAGE ? disk.IMAGE : "Volatile") + ''; html += ''; } html += '\
    \ +'+(vm_info.STATE == "3" ? '\ \ +' : '')+'\ \ - \ + ' ++'\
    '; + // If VM is not RUNNING, then we forget about the attach disk form. if (vm_info.STATE != "3"){ html +='
  • '; return html; } + // Attach disk form html += '\ \ \ @@ -1125,7 +1152,7 @@ function printDisks(vm_info){ \ \ @@ -1186,6 +1213,7 @@ function printDisks(vm_info){ return html; } +// Listeners to the disks operations (detach, saveas, attach) function hotpluggingOps(){ $('button.detachdisk').live('click', function(){ var b = $(this); @@ -1433,7 +1461,7 @@ function setVMAutorefresh(){ },INTERVAL+someTime()); } - +//This is taken from noVNC examples function updateVNCState(rfb, state, oldstate, msg) { var s, sb, cad, klass; s = $D('VNC_status'); @@ -1557,6 +1585,8 @@ function vncIcon(vm){ return gr_icon; } + +// Special error callback in case historical monitoring of VM fails function vmMonitorError(req,error_json){ var message = error_json.error.message; var info = req.request.data[0].monitor; diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index bb808fab4e..e5970d40d4 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -1008,14 +1008,14 @@ function setupQuotasDialog(dialog){ json['TYPE'] = sel.toUpperCase(); - var li = quotaListItem(json) - $('ul#quotas_ul_'+sel,dialog).append($(li).hide().fadeIn()); + var tr = quotaListItem(json) + $('.current_quotas table tbody',dialog).append($(tr).hide().fadeIn()); return false; }); $('form', dialog).submit(function(){ var obj = {}; - $('ul li',this).each(function(){ + $('table tbody tr',this).each(function(){ var json = JSON.parse($(this).attr('quota')); var type = json['TYPE']; delete json['TYPE']; @@ -1037,13 +1037,11 @@ function popUpQuotasDialog(dialog, resource, sel_elems){ $('#image_quota select',dialog).html(im_sel); $('#network_quota select',dialog).html(vn_sel); - + $('table tbody',dialog).empty(); //If only one user is selected we fecth the user's quotas, otherwise we do nothing. if (sel_elems.length == 1){ var id = sel_elems[0]; Sunstone.runAction(resource + '.fetch_quotas',id); - } else { - $('ul',dialog).empty(); }; dialog.dialog('open'); @@ -1054,8 +1052,8 @@ function popUpQuotasDialog(dialog, resource, sel_elems){ function setupQuotaIcons(){ $('.quota_edit_icon').live('click',function(){ var dialog = $(this).parents('form'); - var li = $(this).parents('li'); - var quota = JSON.parse(li.attr('quota')); + var tr = $(this).parents('tr'); + var quota = JSON.parse(tr.attr('quota')); switch (quota.TYPE){ case "VM": $('div#vm_quota input[name="VMS"]',dialog).val(quota.VMS); @@ -1077,7 +1075,7 @@ function setupQuotaIcons(){ break; } $('div#quota_types input[value="'+quota.TYPE.toLowerCase()+'"]',dialog).trigger('click'); - $(this).parents('li').fadeOut(function(){$(this).remove()}); + tr.fadeOut(function(){$(this).remove()}); return false; }); } @@ -1134,8 +1132,8 @@ function parseQuotas(elem){ } for (var i = 0; i < quotas.length; i++){ - var li = quotaListItem(quotas[i]); - results[quotas[i].TYPE] += li; + var tr = quotaListItem(quotas[i]); + results[quotas[i].TYPE] += tr; } return results; } @@ -1143,7 +1141,9 @@ function parseQuotas(elem){ //Receives a quota json object. Returns a nice string out of it. function quotaListItem(quota_json){ var value = JSON.stringify(quota_json) - var str = '
  • ';
    +    var str = '
  • '; return str; } \ No newline at end of file
    '+tr("Attach disk to running VM")+'
    \ \
    '+ + quota_json.TYPE+ + '
    ';
         switch(quota_json.TYPE){
         case "VM":
             str +=  'VMs: ' + quota_json.VMS + (quota_json.VMS_USED ? ' (' + quota_json.VMS_USED + '). ' : ". ") +
    @@ -1164,6 +1164,6 @@ function quotaListItem(quota_json){
                    'Leases: ' + quota_json.LEASES +  (quota_json.LEASES_USED ? ' (' + quota_json.LEASES_USED + '). ': ". ");
             break;
         }
    -    str += '
    '; + str += '