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:
parent
d091f426b5
commit
32f5b81ffc
@ -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
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user