/* -------------------------------------------------------------------------- */ /* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); you may */ /* not use this file except in compliance with the License. You may obtain */ /* a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ /* See the License for the specific language governing permissions and */ /* limitations under the License. */ /* -------------------------------------------------------------------------- */ /*Images tab plugin*/ size_images = 0; var create_image_tmpl ='
\
\

'+tr("Create Image")+'

'+ '
'+ '
'+ '
\
'+tr("Wizard")+'
\
'+tr("Advanced mode")+'
\
\
\
\
\
\
\
\
\ \ \
\
\
\
\ \ \
\
\
\
\ \ \
\
\ \
\
\
\
\ \ \
\
\
\
\ '+tr("Image location")+':\
\
\ \ \ \
\
\
\
\
\ \ \
\
\
\
\
\
\
\
\ \ \
\
\ \ \
\
\
\
\

'+tr("Advanced options")+'

\
\
\
\
\
\
\ \ \
\
\
\
\ \ \
\
\
\
\
\
\ \ \
\
\
\
\
\
\
\ ' + tr("Custom attributes") + '\
\
\
\
\ \ \
\
\
\
\ \ \
\
\
\
\ \ \
\
\
\
\
\
\ \
\
\
\
\
\
\
\
\ \ \
\
\
\
\
\ \
\
\
\
\
\
\ \
\
\
\ \ \
\
\
\ ×\ \ '; var dataTable_images; var $create_image_dialog; var image_actions = { "Image.create" : { type: "create", call: OpenNebula.Image.create, callback: function(request, response){ addImageElement(request, response); $create_image_dialog.foundation('reveal', 'close'); $create_image_dialog.empty(); setupCreateImageDialog(); notifyCustom(tr("Image created"), " ID: " + response.IMAGE.ID, false) }, error: onError }, "Image.create_dialog" : { type: "custom", call: popUpCreateImageDialog }, "Image.list" : { type: "list", call: OpenNebula.Image.list, callback: updateImagesView, error: onError }, "Image.show" : { type : "single", call: OpenNebula.Image.show, callback: function(request, response){ var tab = dataTable_images.parents(".tab"); if (Sunstone.rightInfoVisible(tab)) { // individual view updateImageInfo(request, response); } // datatable row updateImageElement(request, response); }, error: onError }, "Image.refresh" : { type: "custom", call: function () { var tab = dataTable_images.parents(".tab"); if (Sunstone.rightInfoVisible(tab)) { Sunstone.runAction("Image.show", Sunstone.rightInfoResourceId(tab)) } else { waitingNodes(dataTable_images); Sunstone.runAction("Image.list", {force: true}); } } }, "Image.update_template" : { type: "single", call: OpenNebula.Image.update, callback: function(request) { notifyMessage("Template updated correctly"); Sunstone.runAction('Image.show',request.request.data[0][0]); }, error: onError }, "Image.enable" : { type: "multiple", call: OpenNebula.Image.enable, callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, elements: imageElements, error: onError, notify: true }, "Image.disable" : { type: "multiple", call: OpenNebula.Image.disable, callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, elements: imageElements, error: onError, notify: true }, "Image.persistent" : { type: "multiple", call: OpenNebula.Image.persistent, callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, elements: imageElements, error: function (req,error_json) { Sunstone.runAction("Image.show",req.request.data[0]); onError(req,error_json); }, notify: true }, "Image.nonpersistent" : { type: "multiple", call: OpenNebula.Image.nonpersistent, callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, elements: imageElements, error: onError, notify: true }, "Image.delete" : { type: "multiple", call: OpenNebula.Image.del, callback: deleteImageElement, elements: imageElements, error: onError, notify: true }, "Image.chown" : { type: "multiple", call: OpenNebula.Image.chown, callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, elements: imageElements, error: onError, notify: true }, "Image.chgrp" : { type: "multiple", call: OpenNebula.Image.chgrp, callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, elements: imageElements, error: onError, notify: true }, "Image.chmod" : { type: "single", call: OpenNebula.Image.chmod, // callback error: onError, notify: true }, "Image.chtype" : { type: "single", call: OpenNebula.Image.chtype, callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0][0]); }, elements: imageElements, error: onError, notify: true }, "Image.clone_dialog" : { type: "custom", call: popUpImageCloneDialog }, "Image.clone" : { type: "single", call: OpenNebula.Image.clone, error: onError, notify: true }, "Image.help" : { type: "custom", call: function() { hideDialog(); $('div#images_tab div.legend_div').slideToggle(); } }, "Image.rename" : { type: "single", call: OpenNebula.Image.rename, callback: function(request) { notifyMessage(tr("Image renamed correctly")); Sunstone.runAction('Image.show',request.request.data[0][0]); }, error: onError, notify: true }, }; var image_buttons = { "Image.refresh" : { type: "action", layout: "refresh", alwaysActive: true }, // "Sunstone.toggle_top" : { // type: "custom", // layout: "top", // alwaysActive: true // }, "Image.create_dialog" : { type: "create_dialog", layout: "create" }, "Image.chown" : { type: "confirm_with_select", text: tr("Change owner"), layout: "user_select", select: "User", tip: tr("Select the new owner")+":", condition: mustBeAdmin }, "Image.chgrp" : { type: "confirm_with_select", text: tr("Change group"), layout: "user_select", select: "Group", tip: tr("Select the new group")+":", condition: mustBeAdmin }, "Image.enable" : { type: "action", layout: "more_select", text: tr("Enable") }, "Image.disable" : { type: "action", layout: "more_select", text: tr("Disable") }, "Image.persistent" : { type: "action", layout: "more_select", text: tr("Make persistent") }, "Image.nonpersistent" : { type: "action", layout: "more_select", text: tr("Make non persistent") }, "Image.clone_dialog" : { type: "action", layout: "main", text: tr("Clone") }, "Image.delete" : { type: "confirm", layout: "del", text: tr("Delete") }, } var image_info_panel = { "image_info_tab" : { title: tr("Information"), content: "" } } var images_tab = { title: tr("Images"), resource: 'Image', buttons: image_buttons, tabClass: 'subTab', parentTab: 'vresources-tab', content: '
\
\
', search_input: '', list_header: ' '+tr("Images"), info_header: ' '+tr("Image"), subheader: ' '+tr("TOTAL")+' \ '+tr("USED")+'', table: '\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
'+tr("ID")+''+tr("Owner")+''+tr("Group")+''+tr("Name")+''+tr("Datastore")+''+tr("Size")+''+tr("Type")+''+tr("Registration time")+''+tr("Persistent")+''+tr("Status")+''+tr("#VMS")+''+tr("Target")+'
' } Sunstone.addActions(image_actions); Sunstone.addMainTab('images-tab',images_tab); Sunstone.addInfoPanel('image_info_panel',image_info_panel); function imageElements() { return getSelectedNodes(dataTable_images); } // Returns an array containing the values of the image_json and ready // to be inserted in the dataTable function imageElementArray(image_json){ //Changing this? It may affect to the is_persistent() functions. var image = image_json.IMAGE; // KERNEL || RAMDISK || CONTEXT if (image.TYPE == "3" || image.TYPE == "4" || image.TYPE == "5") { return false; } size_images = size_images + parseInt(image.SIZE); //add also persistent/non-persistent selects, type select. return [ '', image.ID, image.UNAME, image.GNAME, image.NAME, image.DATASTORE, image.SIZE, OpenNebula.Helper.image_type(image.TYPE), pretty_time(image.REGTIME), parseInt(image.PERSISTENT) ? "yes" : "no", OpenNebula.Helper.resource_state("image",image.STATE), image.RUNNING_VMS, image.TEMPLATE.TARGET ? image.TEMPLATE.TARGET : '--' ]; } // Callback to update an element in the dataTable function updateImageElement(request, image_json){ var id = image_json.IMAGE.ID; var element = imageElementArray(image_json); updateSingleElement(element,dataTable_images,'#image_'+id); } // Callback to remove an element from the dataTable function deleteImageElement(req){ deleteElement(dataTable_images,'#image_'+req.request.data); } // Callback to add an image element function addImageElement(request, image_json){ var element = imageElementArray(image_json); addElement(element,dataTable_images); } // Callback to refresh the list of images function updateImagesView(request, images_list){ var image_list_array = []; size_images = 0; $.each(images_list,function(){ var image = imageElementArray(this); if (image) image_list_array.push(image); }); updateView(image_list_array,dataTable_images); var size = humanize_size_from_mb(size_images) $(".total_images").text(image_list_array.length); $(".size_images").text(size); } // Callback to update the information panel tabs and pop it up function updateImageInfo(request,img){ var img_info = img.IMAGE; var info_tab = { title : tr("Info"), icon: "fa-info-circle", content: '
\
\ \ \ \ \ \ \ \ \ '+ insert_rename_tr( 'images-tab', "Image", img_info.ID, img_info.NAME)+ '\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
'+tr("Information")+'
'+tr("ID")+''+img_info.ID+'
'+tr("Datastore")+''+img_info.DATASTORE+'
'+tr("Type")+''+OpenNebula.Helper.image_type(img_info.TYPE)+'
\ \
\
'+tr("Register time")+''+pretty_time(img_info.REGTIME)+'
'+tr("Persistent")+''+(parseInt(img_info.PERSISTENT) ? tr("yes") : tr("no"))+'
\ \
\
'+tr("Filesystem type")+''+(typeof img_info.FSTYPE === "string" ? img_info.FSTYPE : "--")+'
'+tr("Size")+''+humanize_size_from_mb(img_info.SIZE)+'
'+tr("State")+''+OpenNebula.Helper.resource_state("image",img_info.STATE)+'
'+tr("Running VMS")+''+img_info.RUNNING_VMS+'
\
\
' + insert_permissions_table('images-tab', "Image", img_info.ID, img_info.UNAME, img_info.GNAME, img_info.UID, img_info.GID) + '
\
\
\
'+ insert_extended_template_table(img_info.TEMPLATE, "Image", img_info.ID, "Attributes") + '
\
' } $("#div_edit_chg_type_link").die(); $("#chg_type_select").die(); $("#div_edit_persistency").die(); $("#persistency_select").die(); // Listener for edit link for type change $("#div_edit_chg_type_link").live("click", function() { $(".value_td_type").html( ''); $('#chg_type_select').val(OpenNebula.Helper.image_type(img_info.TYPE)); }); $("#chg_type_select").live("change", function() { var new_value = $(this).val(); Sunstone.runAction("Image.chtype", img_info.ID, new_value); }); // Listener for edit link for persistency change $("#div_edit_persistency").live("click", function() { $(".value_td_persistency").html( ''); $('#persistency_select').val(parseInt(img_info.PERSISTENT) ? "yes" : "no"); }); $("#persistency_select").live("change", function() { var new_value = $(this).val(); if (new_value=="yes") Sunstone.runAction("Image.persistent",[img_info.ID]); else Sunstone.runAction("Image.nonpersistent",[img_info.ID]); }); var vms_info_tab = { title: tr("VMs"), icon: "fa-cloud", content : '
\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
'+tr("ID")+''+tr("Owner")+''+tr("Group")+''+tr("Name")+''+tr("Status")+''+tr("Used CPU")+''+tr("Used Memory")+''+tr("Host")+''+tr("IPs")+''+tr("Start Time")+''+tr("VNC")+'
\
\
' } Sunstone.updateInfoPanelTab("image_info_panel","image_info_tab",info_tab); Sunstone.updateInfoPanelTab("image_info_panel","image_vms_tab",vms_info_tab); Sunstone.popUpInfoPanel("image_info_panel", "images-tab"); dataTable_image_vMachines = $("#datatable_image_vms", $("#image_info_panel")).dataTable({ "bSortClasses" : false, "bDeferRender": true, "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check",6,7,11] }, { "sWidth": "35px", "aTargets": [0] }, { "bVisible": false, "aTargets": [0]}, { "bVisible": true, "aTargets": Config.tabTableColumns("vms-tab")}, { "bVisible": false, "aTargets": ['_all']}, ] }); infoListener(dataTable_image_vMachines,'VM.show','vms-tab'); if (img_info.VMS) { var vm_ids = img_info.VMS.ID; var vm_ids_map = {}; if (!(vm_ids instanceof Array)) { vm_ids = [vm_ids]; } $.each(vm_ids,function(){ vm_ids_map[this] = true; }); OpenNebula.VM.list({ timeout: true, success: function (request, vm_list){ var vm_list_array = []; $.each(vm_list,function(){ if (vm_ids_map[this.VM.ID]){ //Grab table data from the vm_list vm_list_array.push(vMachineElementArray(this)); } }); updateView(vm_list_array, dataTable_image_vMachines); }, error: onError }); } setPermissionsTable(img_info,''); } function enable_all_datastores() { $('select#disk_type').children('option').each(function() { $(this).removeAttr('disabled'); }); } // Prepare the image creation dialog function setupCreateImageDialog(dialog) { if ($('#create_image_dialog').length == 0) { dialogs_context.append('
'); } $create_image_dialog = $('#create_image_dialog'); var dialog = $create_image_dialog; dialog.html(create_image_tmpl); dialog.addClass("reveal-modal medium").attr("data-reveal", ""); initialize_create_image_dialog(dialog); } function initialize_create_image_dialog(dialog) { setupTips(dialog); $('.advanced',dialog).hide(); $('#advanced_image_create',dialog).click(function(){ $('.advanced',dialog).toggle(); return false; }); $('select#img_type',dialog).change(function(){ var value = $(this).val(); var context = dialog; switch (value){ case "DATABLOCK": $('#datablock_img',context).removeAttr("disabled"); break; default: $('#datablock_img',context).attr('disabled','disabled'); $('#path_image',context).click(); } }); $('#img_path,#img_fstype,#img_size,#file-uploader',dialog).closest('.row').hide(); $("input[name='src_path']", dialog).change(function(){ var context = dialog; var value = $(this).val(); switch (value){ case "path": $('#img_fstype,#img_size,#file-uploader',context).closest('.row').hide(); $('#img_path',context).closest('.row').show(); break; case "datablock": $('#img_path,#file-uploader',context).closest('.row').hide(); $('#img_fstype,#img_size',context).closest('.row').show(); break; case "upload": $('#img_path,#img_fstype,#img_size',context).closest('.row').hide(); $('#file-uploader',context).closest('.row').show(); break; }; }); $('#path_image',dialog).click(); $('#add_custom_var_image_button', dialog).click( function(){ var name = $('#custom_var_image_name',dialog).val(); var value = $('#custom_var_image_value',dialog).val(); if (!name.length || !value.length) { notifyError(tr("Custom attribute name and value must be filled in")); return false; } option= ''; $('select#custom_var_image_box',dialog).append(option); return false; } ); $('#remove_custom_var_image_button', dialog).click( function(){ $('select#custom_var_image_box :selected',dialog).remove(); return false; } ); $('#upload-progress',dialog).css({ border: "1px solid #AAAAAA", position: "relative", width: "258px", height: "15px", display: "inline-block" }); $('#upload-progress div',dialog).css("border","1px solid #AAAAAA"); var img_obj; // Upload is handled by FileUploader vendor plugin var uploader = new qq.FileUploaderBasic({ button: $('#file-uploader',dialog)[0], action: 'upload', multiple: false, params: {}, sizeLimit: 0, showMessage: function(message){ //notifyMessage(message); }, onSubmit: function(id, fileName){ uploader.setParams({ csrftoken: csrftoken, img : JSON.stringify(img_obj), file: fileName }); $('#upload_progress_bars').append('
\
\ '+tr("Uploading...")+'\
\
\
\ \
\
'+id+' '+fileName+'
\
\
'); }, onProgress: function(id, fileName, loaded, total){ $('span.meter', $('#'+id+'progressBar')).css('width', Math.floor(loaded*100/total)+'%') }, onComplete: function(id, fileName, responseJSON){ if (uploader._handler._xhrs[id] && uploader._handler._xhrs[id].status == 500) { onError({}, JSON.parse(uploader._handler._xhrs[id].response) ) $('#'+id+'progressBar').remove(); } else { notifyMessage("Image uploaded correctly"); $('#'+id+'progressBar').remove(); Sunstone.runAction("Image.list"); } return false; }, onCancel: function(id, fileName){ } }); var file_input = false; uploader._button._options.onChange = function(input) { file_input = input; return false; }; $('#create_image_submit',dialog).click(function(){ $create_image_dialog = dialog; var exit = false; var upload = false; $('.img_man',this).each(function(){ if (!$('input',this).val().length){ notifyError(tr("There are mandatory parameters missing")); exit = true; return false; } }); if (exit) { return false; } var ds_id = $('#img_datastore .resource_list_select',dialog).val(); if (!ds_id){ notifyError(tr("Please select a datastore for this image")); return false; }; var img_json = {}; var name = $('#img_name',dialog).val(); img_json["NAME"] = name; var desc = $('#img_desc',dialog).val(); if (desc.length){ img_json["DESCRIPTION"] = desc; } var type = $('#img_type',dialog).val(); img_json["TYPE"]= type; img_json["PERSISTENT"] = $('#img_persistent:checked',dialog).length ? "YES" : "NO"; var dev_prefix = $('#img_dev_prefix',dialog).val(); if (dev_prefix.length){ img_json["DEV_PREFIX"] = dev_prefix; } var driver = $('#img_driver',dialog).val(); if (driver.length) img_json["DRIVER"] = driver; var target = $('#img_target',dialog).val(); if (target) img_json["TARGET"] = target; switch ($('#src_path_select input:checked',dialog).val()){ case "path": path = $('#img_path',dialog).val(); if (path) img_json["PATH"] = path; break; case "datablock": size = $('#img_size',dialog).val(); fstype = $('#img_fstype',dialog).val(); if (size) img_json["SIZE"] = size; if (fstype) img_json["FSTYPE"] = fstype; break; case "upload": upload=true; break; } //Time to add custom attributes $('#custom_var_image_box option',dialog).each(function(){ var attr_name = $(this).attr('name'); var attr_value = $(this).val(); img_json[attr_name] = attr_value; }); img_obj = { "image" : img_json, "ds_id" : ds_id}; //we this is an image upload we trigger FileUploader //to start the upload if (upload){ dialog.foundation('reveal', 'close'); dialog.empty(); setupCreateImageDialog(); uploader._onInputChange(file_input); } else { Sunstone.runAction("Image.create", img_obj); }; return false; }); $('#create_image_submit_manual',dialog).click(function(){ var template=$('#template',dialog).val(); var ds_id = $('#img_datastore_raw .resource_list_select',dialog).val(); if (!ds_id){ notifyError(tr("Please select a datastore for this image")); return false; }; var img_obj = { "image" : { "image_raw" : template }, "ds_id" : ds_id }; Sunstone.runAction("Image.create",img_obj); return false; }); $('#wizard_image_reset_button', dialog).click(function(){ $('#create_image_dialog').html(""); setupCreateImageDialog(); popUpCreateImageDialog(); }); $('#advanced_image_reset_button', dialog).click(function(){ $('#create_image_dialog').html(""); setupCreateImageDialog(); popUpCreateImageDialog(); $("a[href='#img_manual']").click(); }); } function initialize_datastore_info_create_image_dialog(dialog) { var ds_id = $('#img_datastore .resource_list_select',dialog).val(); var ds_id_raw = $('#img_datastore_raw .resource_list_select',dialog).val(); // Filter out DS with type system (1) or file (2) var filter_att = ["TYPE", "TYPE"]; var filter_val = ["1", "2"]; insertSelectOptions('div#img_datastore', dialog, "Datastore", ds_id, false, null, filter_att, filter_val); insertSelectOptions('div#img_datastore_raw', dialog, "Datastore", ds_id_raw, false, null, filter_att, filter_val); $('#file-uploader input',dialog).removeAttr("style"); $('#file-uploader input',dialog).attr('style','margin:0;width:256px!important'); } function popUpCreateImageDialog(){ $create_image_dialog = $('#create_image_dialog'); initialize_datastore_info_create_image_dialog($create_image_dialog); $create_image_dialog.foundation().foundation('reveal', 'open'); $("input#img_name",$create_image_dialog).focus(); } function is_persistent_image(id){ var data = getElementData(id,"#image",dataTable_images)[8]; return $(data).is(':checked'); }; function setupImageCloneDialog(){ //Append to DOM dialogs_context.append('
'); var dialog = $('#image_clone_dialog',dialogs_context); //Put HTML in place var html = '
\

'+tr("Clone Image")+'

\
\
\
\
\
\
'+tr("Several image are selected, please choose prefix to name the new copies")+':
\
\
\
\
\
\ \ \ \
\
\
\ \
\ ×\
\ '; dialog.html(html); dialog.addClass("reveal-modal").attr("data-reveal", ""); $('form',dialog).submit(function(){ var name = $('input', this).val(); var sel_elems = imageElements(); if (!name || !sel_elems.length) notifyError('A name or prefix is needed!'); if (sel_elems.length > 1){ for (var i=0; i< sel_elems.length; i++) //If we are cloning several images we //use the name as prefix Sunstone.runAction('Image.clone', sel_elems[i], name+getImageName(sel_elems[i])); } else { Sunstone.runAction('Image.clone',sel_elems[0],name) }; dialog.foundation('reveal', 'close') setTimeout(function(){ Sunstone.runAction('Image.refresh'); }, 1500); return false; }); } function popUpImageCloneDialog(){ var dialog = $('#image_clone_dialog'); var sel_elems = imageElements(); //show different text depending on how many elements are selected if (sel_elems.length > 1){ $('.clone_one',dialog).hide(); $('.clone_several',dialog).show(); $('input',dialog).val('Copy of '); } else { $('.clone_one',dialog).show(); $('.clone_several',dialog).hide(); $('input',dialog).val('Copy of '+getImageName(sel_elems[0])); }; $(dialog).foundation().foundation('reveal', 'open'); $("input[name='name']",dialog).focus(); } //The DOM is ready at this point $(document).ready(function(){ var tab_name = 'images-tab'; if (Config.isTabEnabled(tab_name)) { dataTable_images = $("#datatable_images",main_tabs_context).dataTable({ "bSortClasses" : false, "bDeferRender": true, "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "35px", "aTargets": [0] }, { "bVisible": true, "aTargets": Config.tabTableColumns(tab_name)}, { "bVisible": false, "aTargets": ['_all']} ] }); $('#image_search').keyup(function(){ dataTable_images.fnFilter( $(this).val() ); }) dataTable_images.on('draw', function(){ recountCheckboxes(dataTable_images); }) Sunstone.runAction("Image.list"); setupCreateImageDialog(); setupImageCloneDialog(); initCheckAllBoxes(dataTable_images); tableCheckboxesListener(dataTable_images); infoListener(dataTable_images,'Image.show'); $('div#images_tab div.legend_div').hide(); dataTable_images.fnSort( [ [1,config['user_config']['table_order']] ] ); } });