1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

Sunstone (#1314): Enable volatile disks hotplugging, improve quotas representation

(cherry picked from commit fad8616147b0bca1adb10a90ead14d6b0d5e3fa0)
This commit is contained in:
Hector Sanjuan 2012-07-02 14:28:35 +02:00 committed by Ruben S. Montero
parent d091f426b5
commit 32f5b81ffc
4 changed files with 94 additions and 65 deletions

View File

@ -105,21 +105,15 @@ var group_quotas_tmpl = '<form id="group_quotas_form" action="">\
<button style="width:100px!important;" class="add_remove_button add_button" id="add_quota_button" value="add_quota">'+tr("Add/edit quota")+'</button>\
<div class="clear"></div>\
<div class="clear"></div>\
<div>'+tr("Current quotas")+':</div>\
<div class="current_quotas">\
<label>'+tr("VM quota")+':</label><br />\
<ul id="quotas_ul_vm">\
</ul>\
<label>'+tr("Datastore quotas")+':</label><br />\
<ul id="quotas_ul_datastore">\
</ul>\
<label>'+tr("Image quotas")+':</label><br />\
<ul id="quotas_ul_image">\
</ul>\
<label>'+tr("Network quotas")+':</label><br />\
<ul id="quotas_ul_network">\
</ul>\
</div>\
<table class="info_table" style="width:640px;margin-top:0;">\
<thead><tr>\
<th>'+tr("Type")+'</th>\
<th style="width:100%;">'+tr("Quota")+'</th>\
<th>'+tr("Edit")+'</th></tr></thead>\
<tbody>\
</tbody>\
</table>\
<div class="form_buttons">\
<button class="button" type="submit" value="Group.set_quota">'+tr("Apply changes")+'</button>\
</div>\
@ -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
},

View File

@ -146,20 +146,15 @@ var user_quotas_tmpl = '<form id="user_quotas_form" action="">\
<button style="width:100px!important;" class="add_remove_button add_button" id="add_quota_button" value="add_quota">'+tr("Add/edit quota")+'</button>\
<div class="clear"></div>\
<div class="clear"></div>\
<div>'+tr("Current quotas")+':</div>\
<div class="current_quotas">\
<label>'+tr("VM quota")+':</label><br />\
<ul id="quotas_ul_vm">\
</ul>\
<label>'+tr("Datastore quotas")+':</label><br />\
<ul id="quotas_ul_datastore">\
</ul>\
<label>'+tr("Image quotas")+':</label><br />\
<ul id="quotas_ul_image">\
</ul>\
<label>'+tr("Network quotas")+':</label><br />\
<ul id="quotas_ul_network">\
</ul>\
<table class="info_table" style="width:640px;margin-top:0;">\
<thead><tr>\
<th>'+tr("Type")+'</th>\
<th style="width:100%;">'+tr("Quota")+'</th>\
<th>'+tr("Edit")+'</th></tr></thead>\
<tbody>\
</tbody>\
</table>\
</div>\
<div class="form_buttons">\
<button class="button" type="submit" value="User.set_quota">'+tr("Apply changes")+'</button>\
@ -329,10 +324,10 @@ var user_actions = {
// quota objects with html code (<li>) 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){
'</table>'
};
var quotas_tab_html = '';
if (!$.isEmptyObject(user_info.VM_QUOTA))
quotas_tab_html += '<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.VM_QUOTA)+'</tbody>\
</table>'
if (!$.isEmptyObject(user_info.DATASTORE_QUOTA))
quotas_tab_html += '<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.DATASTORE_QUOTA)+'</tbody>\
</table>'
if (!$.isEmptyObject(user_info.IMAGE_QUOTA))
quotas_tab_html += '<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.IMAGE_QUOTA)+'</tbody>\
</table>';
if (!$.isEmptyObject(user_info.NETWORK_QUOTA))
quotas_tab_html += '<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.NETWORK_QUOTA)+'</tbody>\
</table>';
var quotas_tab = {
title : tr("User quotas"),
content : '\
<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.DATASTORE_QUOTA)+'</tbody>\
</table>\
<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.VM_QUOTA)+'</tbody>\
</table>\
<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.IMAGE_QUOTA)+'</tbody>\
</table>\
<table class="info_table">\
<tbody>'+prettyPrintJSON(user_info.NETWORK_QUOTA)+'</tbody>\
</table>'
content : quotas_tab_html
};
Sunstone.updateInfoPanelTab("user_info_panel","user_info_tab",info_tab);

View File

@ -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 = ' <table id="vm_history_table" class="info_table" style="width:80%">\
<thead>\
@ -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") + '</td>';
html += '<td class="value_td">\
'+(vm_info.STATE == "3" ? '\
<button value="VM.detachdisk" class="detachdisk" style="float:right;color:#555555;height:26px;"><i class="icon-trash icon-large"></i></button>\
' : '')+'\
<button value="VM.saveas" class="saveas" style="float:right;margin-right:10px;color:#555555;height:26px;"><i class="icon-download icon-large"></i></button>\
<input style="float:right;width:9em;margin-right:10px;margin-top:3px;" type="text" value="saveas_'+vm_info.ID+'_'+disk.DISK_ID+'" name="saveas_name"></input>\
<input style="float:right;width:9em;margin-right:10px;margin-top:3px;" type="text" value="saveas_'+vm_info.ID+'_'+disk.DISK_ID+'" name="saveas_name"></input>'
+'\
</td>';
}
html += '</tbody>\
</table>';
// If VM is not RUNNING, then we forget about the attach disk form.
if (vm_info.STATE != "3"){
html +='</form>';
return html;
}
// Attach disk form
html += '<table class="info_table">\
<thead>\
<tr><th colspan="2">'+tr("Attach disk to running VM")+'</th></tr>\
@ -1125,7 +1152,7 @@ function printDisks(vm_info){
<td class="value_td">\
<select id="attach_disk_type" style="width:12em;">\
<option value="image">'+tr("Existing image")+'</option>\
<!-- <option value="volatile">'+tr("Volatile disk")+'</option>-->\
<option value="volatile">'+tr("Volatile disk")+'</option>\
</select>\
</td>\
</tr>\
@ -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;

View File

@ -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 = '<li quota=\''+value+'\'><pre style="margin:0;">';
var str = '<tr quota=\''+value+'\'><td>'+
quota_json.TYPE+
'</td><td style="width:100%;"><pre style="margin:0;">';
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 += '<i class="quota_edit_icon icon-pencil"></i></pre></li>';
str += '</td><td><i class="quota_edit_icon icon-pencil"></i></pre></td></tr>';
return str;
}