1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-26 06:50:09 +03:00

Feature #1356: Add hotplugging to Self-Service

(cherry picked from commit 5a8c40148211cfc3c78ecaacbd5c3f45d665e294)
This commit is contained in:
Hector Sanjuan 2012-09-04 11:22:47 +02:00 committed by Ruben S. Montero
parent 6bab124c84
commit 6746a8bb31
3 changed files with 189 additions and 187 deletions

View File

@ -500,6 +500,19 @@ var OCCI = {
},
"startvnc" : function(params){
OCCI.VM.vnc(params,"startvnc");
},
"attachdisk" : function(params){
var action_obj = {"disk_template": params.data.extra_param};
OCCI.Action.simple_action(params,OCCI.VM.resource,
"attachdisk",
params.data.extra_param);
},
"detachdisk" : function(params){
// extra param is disk id
var action_obj = '<DISK id="'+params.data.extra_param+'"/>'
OCCI.Action.simple_action(params,OCCI.VM.resource,
"detachdisk", action_obj);
}
/*
"monitor" : function(params){

View File

@ -241,14 +241,6 @@ var vm_actions = {
notify: true
},
"VM.saveasmultiple" : {
type: "custom",
call: function(){
var elems = vmElements();
popUpSaveasDialog(elems);
}
},
"VM.saveas" : {
type: "single",
call: OCCI.VM.saveas,
@ -256,13 +248,6 @@ var vm_actions = {
error:onError
},
"VM.saveas_disks" : {
type: "single",
call: OCCI.VM.show,
callback: saveasDisksCallback,
error: onError
},
"VM.getInstanceTypes" : {
type: "list",
call: OCCI.Instance_type.list,
@ -286,6 +271,26 @@ var vm_actions = {
callback: vncCallback,
error: onError,
notify: true
},
"VM.attachdisk" : {
type: "single",
call: OCCI.VM.attachdisk,
callback: updateVMachineElement,
error: onError,
notify: true
},
"VM.detachdisk" : {
type: "single",
call: OCCI.VM.detachdisk,
callback: function(req,res){
setTimeout(function(req,res){
Sunstone.runAction("VM.show", req.request.data[0][0])
},1000,req);
},
error: onError,
notify: true
}
/*
@ -382,8 +387,8 @@ var vm_info_panel = {
title: tr("Compute resource"),
content: ""
},
"vm_disks_tab" : {
title: tr("Disks"),
"vm_hotplugging_tab" : {
title: tr("Disks & Hotplugging"),
content: ""
},
"vm_networks_tab" : {
@ -464,6 +469,11 @@ function updateVMachineElement(request, vm_json){
var id = vm_json.COMPUTE.ID;
var element = vMachineElementArray(vm_json);
updateSingleElement(element,dataTable_vMachines,'#vm_'+id)
//we update this too, even if it is not shown.
var $hotplugging_tab = $('div#vm_info_panel div#vm_hotplugging_tab');
$('#hotplugging_form',
$hotplugging_tab).replaceWith(printDisks(vm_json.COMPUTE));
}
// Callback to delete a single element from the list
@ -562,47 +572,9 @@ function updateVMInfo(request,vm){
<button class="vm_close_dialog_link"/></div>'
};
var disks_str = '<table class="info_table">\
<thead>\
<tr><th colspan="2">'+tr("Disks information")+'</th></tr>\
</thead><tbody>';
var disks = vm_info.DISK;
if (disks){
if (disks.constructor != Array) // 1lease
disks = [disks];
for (var i=0;i<disks.length; i++){
disks_str += '<tr>\
<td class="key_td">'+tr("ID")+'</td>\
<td class="value_td">'+disks[i].id+'</td>\
</tr>\
<tr>\
<td class="key_td">'+tr("Name")+'</td>\
<td class="value_td">'+disks[i].STORAGE.name+'</td>\
</tr>\
<tr>\
<td class="key_td">'+tr("Target")+'</td>\
<td class="value_td">'+disks[i].TARGET+'</td>\
</tr>\
<tr>\
<td class="key_td">'+tr("Type")+'</td>\
<td class="value_td">'+disks[i].TYPE+'</td>\
</tr><tr><td></td><td></td></tr>';
};
} else {
disks_str += '<tr><td class="key_td">'+
tr("No disks defined")+'</td><td></td></tr>';
};
disks_str += '</tbody></table>\
<div class="form_buttons">\
<button class="vm_close_dialog_link"/></div>';
var disks_tab = {
title : tr("Disks"),
content : disks_str
var hotplugging_tab = {
title : tr("Disks & Hotplugging"),
content : printDisks(vm_info)
};
var networks_str = '<table class="info_table">\
@ -658,7 +630,7 @@ function updateVMInfo(request,vm){
*/
Sunstone.updateInfoPanelTab("vm_info_panel","vm_info_tab",info_tab);
Sunstone.updateInfoPanelTab("vm_info_panel","vm_disks_tab",disks_tab);
Sunstone.updateInfoPanelTab("vm_info_panel","vm_hotplugging_tab",hotplugging_tab);
Sunstone.updateInfoPanelTab("vm_info_panel","vm_networks_tab",networks_tab);
//Sunstone.updateInfoPanelTab("vm_info_panel","vm_monitoring_tab",monitoring_tab);
@ -675,6 +647,150 @@ function updateVMInfo(request,vm){
// };
}
// 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
2, //name col
[],
[]
);
var html ='\
<form style="display:inline-block;width:100%" id="hotplugging_form" vmid="'+vm_info.ID+'">\
<table class="info_table">\
<thead>\
<tr><th colspan="2">'+tr("Disks information - Save As and Detach")+'</th></tr>\
</thead>\
<tbody>\
';
var disks = []
if ($.isArray(vm_info.DISK))
disks = vm_info.DISK
else if (!$.isEmptyObject(vm_info.DISK))
disks = [vm_info.DISK]
if (!disks.length){
html += '<tr id="no_disks_tr"><td class="key_td">\
'+tr("No disks to show")+'\
</td><td class="value_td"></td></tr>';
}
else {
for (var i = 0; i < disks.length; i++){
var disk = disks[i];
html += '<tr disk_id="'+(disk.id)+'"><td class="key_td">';
html += disk.STORAGE.name + '</td>';
html += '<td class="value_td">\
'+(vm_info.STATE == "ACTIVE" ? '\
<button value="VM.detachdisk" class="detachdisk" style="float:right;color:#555555;height:26px;">'+tr("Detach")+' <i class="icon-remove icon-large"></i></button>\
' : '')+'\
<button value="VM.saveas" class="saveas" style="float:right;margin-right:10px;color:#555555;height:26px;">'+tr("Save")+' <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.STORAGE.name+'" name="saveas_name"></input>\
<label style="float:right;margin-top:4px;">'+tr("Save_as name")+':</label>'
+'\
</td>';
}
}
html += '</tbody>\
</table>';
// If VM is not RUNNING, then we forget about the attach disk form.
if (vm_info.STATE != "ACTIVE"){
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>\
</thead>\
<tbody>\
<tr><td class="key_td"><label>'+tr("Select image")+':</label></td>\
<td class="value_td">\
<select name="IMAGE_ID" style="width:12em;">\
'+im_sel+'\
</select>\
</td>\
</tr>\
<tr><td class="key_td"><label>'+tr("Target")+':</label></td>\
<td class="value_td">\
<input type="text" name="TARGET" style="width:8em;"></input>\
</td>\
</tr>\
<tr><td class="key_td"></td>\
<td class="value_td">\
<button type="submit" value="VM.attachdisk">'+tr("Attach")+'</button>\
</td>\
</tr>\
</tbody>\
</table></form>';
return html;
}
// Listeners to the disks operations (detach, saveas, attach)
function hotpluggingOps(){
$('button.detachdisk').live('click', function(){
var b = $(this);
var vm_id = b.parents('form').attr('vmid');
var disk_id = b.parents('tr').attr('disk_id');
Sunstone.runAction('VM.detachdisk', vm_id, disk_id);
b.html(spinner);
return false;
});
$('button.saveas').live('click', function(){
var b = $(this);
var vm_id = b.parents('form').attr('vmid');
var disk_id = b.parents('tr').attr('disk_id');
var parent = b.parent();
var image_name = $('input[name="saveas_name"]',parent).val();
if (!image_name){
notifyError('Please provide a name for the new image');
return false;
}
var obj = {
disk_id : disk_id,
image_name : image_name,
};
Sunstone.runAction('VM.saveas', vm_id, obj);
b.html(spinner);
return false;
});
$('#hotplugging_form').live('submit',function(){
var vm_id = $(this).attr('vmid');
var disk_obj = {};
var im_id = $('select[name="IMAGE_ID"]',this).val();
if (!im_id) {
notifyError(tr("Please select an image to attach"));
return false;
}
var image_id = $('select[name="IMAGE_ID"]',this).val();
var url = location.protocol + "//" + location.host;
var href = url + '/storage/' + image_id
var target = $('input[name="TARGET"]',this).val();
var str = '<STORAGE href="'+href+'" />';
if (target) str += '<TARGET>'+target+'</TARGET>';
Sunstone.runAction("VM.attachdisk", vm_id, str);
return false;
});
}
// Open creation dialog
function popUpCreateVMDialog(){
Sunstone.popUpInfoPanel("vm_create_panel");
@ -813,131 +929,6 @@ function popUpCreateVMDialog(){
});
}
//Prepares a dialog to saveas a VM
function setupSaveasDialog(){
//Append to DOM
dialogs_context.append('<div id="saveas_vm_dialog" title=\"'+tr("Take snapshot")+'\"></div>');
$saveas_vm_dialog = $('#saveas_vm_dialog',dialogs_context);
var dialog = $saveas_vm_dialog;
//Put HTML in place
dialog.html('\
<form id="saveas_vm_form" action="javascript:alert(\'js error!\');">\
<div id="saveas_tabs">\
</div>\
<div class="form_buttons">\
<button id="vm_saveas_proceed" value="">'+tr("OK")+'</button>\
<button id="vm_saveas_cancel" value="">'+tr("Cancel")+'</button>\
</div>\
</fieldset>\
</form>');
dialog.dialog({
autoOpen:false,
width:600,
modal:true,
height:350,
resizable:true
});
$('#saveas_vm_form',dialog).submit(function(){
var elems = $('#saveas_tabs div.saveas_tab',this);
var args = [];
$.each(elems,function(){
var id = $('#vm_id',this).text();
var disk_id = $('#vm_disk_id',this).val();
var image_name = $('#image_name',this).val();
if (!id.length || !disk_id.length || !image_name.length) {
notifyError(tr("Skipping VM ")+id+". "+
tr("No disk id or image name specified"));
}
else {
var obj = {
disk_id : disk_id,
image_name : image_name
};
args.push(id);
Sunstone.runAction("VM.saveas",id,obj);
}
});
if (args.length > 0){
notifySubmit("VM.saveas",args);
}
$saveas_vm_dialog.dialog('close');
return false;
});
$('#vm_saveas_cancel',dialog).click(function(){
$saveas_vm_dialog.dialog('close');
return false;
});
}
function popUpSaveasDialog(elems){
var dialog = $saveas_vm_dialog;
$('#saveas_tabs',dialog).tabs('destroy');
$('#saveas_tabs',dialog).empty();
$('#saveas_tabs',dialog).html('<ul></ul>');
$.each(elems,function(){
var li = '<li><a href="#saveas_tab_'+this+'">VM '+this+'</a></li>'
$('#saveas_tabs ul',dialog).append(li);
var tab = '<div class="saveas_tab" id="saveas_tab_'+this+'">\
<div id="vm_id_text">'+tr("Saveas for VM with ID")+' <span id="vm_id">'+this+'</span></div>\
<fieldset>\
<div>\
<label for="vm_disk_id">'+tr("Select disk")+':</label>\
<select id="vm_disk_id" name="vm_disk_id">\
<option value="">'+tr("Retrieving")+'...</option>\
</select>\
</div>\
<div>\
<label for="image_name">'+tr("Image name")+':</label>\
<input type="text" id="image_name" name="image_name" value="" />\
</div>\
</fieldset>\
</div>';
$('#saveas_tabs',dialog).append(tab);
Sunstone.runAction("VM.saveas_disks",this);
});
$('#saveas_tabs',dialog).tabs();
$('button',dialog).button();
dialog.dialog('open');
}
function saveasDisksCallback(req,response){
var vm_info = response.COMPUTE;
var id=vm_info.ID;
var select="";
var gen_option = function(id, name, source){
if (name){
return '<option value="'+id+'">'+name+" ("+tr("disk id")+": "+id+')</option>';
}
else {
return '<option value="'+id+'">'+source+" ("+tr("disk id")+": "+id+')</option>';
}
}
var disks = vm_info.DISK;
if (!disks) { select = '<option value="">'+tr("No disks defined")+'</option>';}
else if (disks.constructor == Array) //several disks
{
for (var i=0;i<disks.length;i++){
select += gen_option(disks[i].id,disks[i].STORAGE.name,null);
}
} else {
select+= gen_option(disks.id,disks.STORAGE.name,null);
}
//introduce options in the right tab
$('#saveas_tabs #saveas_tab_'+id+' #vm_disk_id',$saveas_vm_dialog).html(select);
}
function popUpVMDashboard(){
var count = dataTable_vMachines.fnGetNodes().length;
popDialog(vm_dashboard);
@ -1125,11 +1116,10 @@ $(document).ready(function(){
'','',''],dataTable_vMachines);
Sunstone.runAction("VM.list");
//setupCreateVMDialog();
setupSaveasDialog();
setVMAutorefresh();
setupVNC();
hotpluggingOps();
initCheckAllBoxes(dataTable_vMachines);
tableCheckboxesListener(dataTable_vMachines);
infoListener(dataTable_vMachines,'VM.showinfo');

View File

@ -1221,7 +1221,6 @@ function hotpluggingOps(){
var b = $(this);
var vm_id = b.parents('form').attr('vmid');
var disk_id = b.parents('tr').attr('disk_id');
var parent = b.parent();
Sunstone.runAction('VM.detachdisk', vm_id, disk_id);