diff --git a/bugfix/files-tab.js b/bugfix/files-tab.js new file mode 100644 index 0000000..c110c55 --- /dev/null +++ b/bugfix/files-tab.js @@ -0,0 +1,847 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var create_file_tmpl ='
\ +
\ +

'+tr("Create File")+'

'+ + '
'+ + '
'+ + '
\ +
'+tr("Wizard")+'
\ +
'+tr("Advanced mode")+'
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ +
\ +
\ + '+tr("Image location")+':\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ +
\ + \ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ + ×\ +
\ +'; + +var dataTable_files; +var $create_file_dialog; + +var file_actions = { + + "File.create" : { + type: "create", + call: OpenNebula.Image.create, + callback: function(request, response) { + // Reset the create wizard + $create_file_dialog.foundation('reveal', 'close'); + $create_file_dialog.empty(); + setupCreateFileDialog(); + + addFileElement(request, response); + notifyCustom(tr("File created"), " ID: " + response.IMAGE.ID, false); + }, + error: onError + }, + + "File.create_dialog" : { + type: "custom", + call: popUpCreateFileDialog + }, + + "File.list" : { + type: "list", + call: OpenNebula.Image.list, + callback: updateFilesView, + error: onError + }, + + "File.show" : { + type : "single", + call: OpenNebula.Image.show, + callback: function(request, response){ + var tab = dataTable_files.parents(".tab"); + + if (Sunstone.rightInfoVisible(tab)) { + // individual view + updateFileInfo(request, response); + } + + // datatable row + updateFileElement(request, response); + }, + error: onError + }, + + "File.refresh" : { + type: "custom", + call: function () { + var tab = dataTable_files.parents(".tab"); + if (Sunstone.rightInfoVisible(tab)) { + Sunstone.runAction("File.show", Sunstone.rightInfoResourceId(tab)) + } else { + waitingNodes(dataTable_files); + Sunstone.runAction("File.list", {force: true}); + } + } + }, + + "File.update_template" : { + type: "single", + call: OpenNebula.Image.update, + callback: function(request) { + notifyMessage("Template updated correctly"); + Sunstone.runAction('File.show',request.request.data[0][0]); + }, + error: onError + }, + + "File.enable" : { + type: "multiple", + call: OpenNebula.Image.enable, + callback: function (req) { + Sunstone.runAction("File.show",req.request.data[0]); + }, + elements: fileElements, + error: onError, + notify: true + }, + + "File.disable" : { + type: "multiple", + call: OpenNebula.Image.disable, + callback: function (req) { + Sunstone.runAction("File.show",req.request.data[0]); + }, + elements: fileElements, + error: onError, + notify: true + }, + + "File.delete" : { + type: "multiple", + call: OpenNebula.Image.del, + callback: deleteFileElement, + elements: fileElements, + error: onError, + notify: true + }, + + "File.chown" : { + type: "multiple", + call: OpenNebula.Image.chown, + callback: function (req) { + Sunstone.runAction("File.show",req.request.data[0][0]); + }, + elements: fileElements, + error: onError, + notify: true + }, + + "File.chgrp" : { + type: "multiple", + call: OpenNebula.Image.chgrp, + callback: function (req) { + Sunstone.runAction("File.show",req.request.data[0][0]); + }, + elements: fileElements, + error: onError, + notify: true + }, + + "File.chmod" : { + type: "single", + call: OpenNebula.Image.chmod, +// callback + error: onError, + notify: true + }, + + "File.chtype" : { + type: "single", + call: OpenNebula.Image.chtype, + callback: function (req) { + Sunstone.runAction("File.show",req.request.data[0][0]); + }, + elements: fileElements, + error: onError, + notify: true + }, + "File.help" : { + type: "custom", + call: function() { + hideDialog(); + $('div#files_tab div.legend_div').slideToggle(); + } + }, + "File.rename" : { + type: "single", + call: OpenNebula.Image.rename, + callback: function(request) { + notifyMessage(tr("File renamed correctly")); + Sunstone.runAction('File.show',request.request.data[0]); + }, + error: onError, + notify: true + }, +}; + + +var file_buttons = { + "File.refresh" : { + type: "action", + layout: "refresh", + alwaysActive: true + }, +// "Sunstone.toggle_top" : { +// type: "custom", +// layout: "top", +// alwaysActive: true +// }, + "File.create_dialog" : { + type: "create_dialog", + layout: "create" + }, + "File.chown" : { + type: "confirm_with_select", + text: tr("Change owner"), + layout: "user_select", + select: "User", + tip: tr("Select the new owner")+":", + condition: mustBeAdmin + }, + "File.chgrp" : { + type: "confirm_with_select", + text: tr("Change group"), + layout: "user_select", + select: "Group", + tip: tr("Select the new group")+":", + condition: mustBeAdmin + }, + "File.enable" : { + type: "action", + layout: "more_select", + text: tr("Enable") + }, + "File.disable" : { + type: "action", + layout: "more_select", + text: tr("Disable") + }, + "File.delete" : { + type: "confirm", + layout: "del", + text: tr("Delete") + } +} + +var file_info_panel = { + "file_info_tab" : { + title: tr("Information"), + content: "" + } +} + +var files_tab = { + title: tr("Files & Kernels"), + resource: 'File', + buttons: file_buttons, + tabClass: 'subTab', + parentTab: 'vresources-tab', + content: '
\ +
\ +
', + search_input: '', + list_header: ' '+tr("Files & Kernels"), + info_header: ' '+tr("File"), + subheader: ' '+tr("TOTAL")+' \ + '+tr("SIZE")+'', + 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(file_actions); +Sunstone.addMainTab('files-tab',files_tab); +Sunstone.addInfoPanel('file_info_panel',file_info_panel); + + +function fileElements() { + return getSelectedNodes(dataTable_files); +} + +// Returns an array containing the values of the file_json and ready +// to be inserted in the dataTable +function fileElementArray(file_json){ + //Changing this? It may affect to the is_persistent() functions. + var file = file_json.IMAGE; + + // OS || CDROM || DATABLOCK + if (file.TYPE == "0" || file.TYPE == "1" || file.TYPE == "2") { + return false; + } + + + size_files = size_files + parseInt(file.SIZE); + + //add also persistent/non-persistent selects, type select. + return [ + '', + file.ID, + file.UNAME, + file.GNAME, + file.NAME, + file.DATASTORE, + file.SIZE, + OpenNebula.Helper.image_type(file.TYPE), + pretty_time(file.REGTIME), + parseInt(file.PERSISTENT) ? "yes" : "no", + OpenNebula.Helper.resource_state("image",file.STATE), + file.RUNNING_VMS, + file.TEMPLATE.TARGET ? file.TEMPLATE.TARGET : '--' + ]; +} + +// Callback to update an element in the dataTable +function updateFileElement(request, file_json){ + var id = file_json.IMAGE.ID; + var element = fileElementArray(file_json); + updateSingleElement(element,dataTable_files,'#file_'+id); +} + +// Callback to remove an element from the dataTable +function deleteFileElement(req){ + deleteElement(dataTable_files,'#file_'+req.request.data); +} + +// Callback to add an file element +function addFileElement(request, file_json){ + var element = fileElementArray(file_json); + addElement(element,dataTable_files); +} + +// Callback to refresh the list of files +function updateFilesView(request, files_list){ + var file_list_array = []; + + size_files = 0; + + $.each(files_list,function(){ + var file = fileElementArray(this); + if (file) + file_list_array.push(file); + }); + + updateView(file_list_array,dataTable_files); + + var size = humanize_size_from_mb(size_files) + + $(".total_files").text(file_list_array.length); + $(".size_files").text(size); +} + +// Callback to update the information panel tabs and pop it up +function updateFileInfo(request,file){ + var file_info = file.IMAGE; + var info_tab = { + title : tr("Info"), + icon: "fa-info-circle", + content: + '
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + '+ + insert_rename_tr( + 'files-tab', + "File", + file_info.ID, + file_info.NAME)+ + '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
'+tr("File")+' - '+file_info.NAME+'
'+tr("ID")+''+file_info.ID+'
'+tr("Datastore")+''+file_info.DATASTORE+'
'+tr("Type")+''+OpenNebula.Helper.image_type(file_info.TYPE)+'
\ + \ +
\ +
'+tr("Register time")+''+pretty_time(file_info.REGTIME)+'
'+tr("Filesystem type")+''+(typeof file_info.FSTYPE === "string" ? file_info.FSTYPE : "--")+'
'+tr("Size")+''+humanize_size_from_mb(file_info.SIZE)+'
'+tr("State")+''+OpenNebula.Helper.resource_state("file",file_info.STATE)+'
'+tr("Running VMS")+''+file_info.RUNNING_VMS+'
\ +
\ +
' + + insert_permissions_table('files-tab', + "File", + file_info.ID, + file_info.UNAME, + file_info.GNAME, + file_info.UID, + file_info.GID) + + '
\ +
\ +
\ +
'+ + insert_extended_template_table(file_info.TEMPLATE, + "File", + file_info.ID, + "Attributes") + + '
\ +
' + } + + $("#div_edit_chg_type_files_link").die(); + $("#chg_type_select_files").die(); + $("#div_edit_persistency_files").die(); + $("#persistency_select_files").die(); + + + // Listener for edit link for type change + $("#div_edit_chg_type_files_link").live("click", function() { + $(".value_td_type_files").html( + ''); + + $('#chg_type_select_files').val(OpenNebula.Helper.image_type(file_info.TYPE)); + }); + + $("#chg_type_select_files").live("change", function() { + var new_value = $(this).val(); + Sunstone.runAction("File.chtype", file_info.ID, new_value); + }); + + + Sunstone.updateInfoPanelTab("file_info_panel","file_info_tab",info_tab); + Sunstone.popUpInfoPanel("file_info_panel", "files-tab"); + + setPermissionsTable(file_info,''); +} + +function enable_all_datastores() +{ + + $('select#disk_type').children('option').each(function() { + $(this).removeAttr('disabled'); + }); +} + +// Prepare the file creation dialog +function setupCreateFileDialog(){ + dialogs_context.append('
'); + $create_file_dialog = $('#create_file_dialog',dialogs_context); + + var dialog = $create_file_dialog; + dialog.html(create_file_tmpl); + + dialog.addClass("reveal-modal medium").attr("data-reveal", ""); + + $('#files_file-uploader',dialog).closest('.row').hide(); + + $("input[name='src_path']", dialog).change(function(){ + var context = $create_file_dialog; + var value = $(this).val(); + switch (value){ + case "path": + $('#files_file-uploader',context).closest('.row').hide(); + $('#file_path',context).closest('.row').show(); + break; + case "upload": + $('#file_path',context).closest('.row').hide(); + $('#files_file-uploader',context).closest('.row').show(); + break; + }; + }); + + + $('#path_file',dialog).click(); + + $('#upload-progress',dialog).css({ + border: "1px solid #AAAAAA", + position: "relative", +// bottom: "29px", + width: "258px", +// left: "133px", + height: "15px", + display: "inline-block" + }); + $('#upload-progress div',dialog).css("border","1px solid #AAAAAA"); + + var file_obj; + + // Upload is handled by FileUploader vendor plugin + var uploader = new qq.FileUploaderBasic({ + button: $('#files_file-uploader',$create_file_dialog)[0], + action: 'upload', + multiple: false, + params: {}, + sizeLimit: 0, + showMessage: function(message){ + //notifyMessage(message); + }, + onSubmit: function(id, fileName){ + //set url params + //since the body is the upload, we need the pass + //the file info here + uploader.setParams({ + csrftoken: csrftoken, + img : JSON.stringify(file_obj), + file: fileName + }); + //we pop up an upload progress dialog + var pos_top = $(window).height() - 120; + var pos_left = 220; + + $('#files_upload_progress_bars').append('
\ +
\ + '+tr("Uploading...")+'\ +
\ +
\ +
\ + \ +
\ +
'+id+' '+fileName+'
\ +
\ +
'); + + $('#files'+id+'cancel_upload').click(function(){ + uploader.cancel(); + }) + }, + onProgress: function(id, fileName, loaded, total){ + //update upload dialog with current progress + $('span.meter', $('#files'+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) ) + $('#files'+id+'progressBar').remove(); + } else { + notifyMessage("File uploaded correctly"); + Sunstone.runAction("File.list"); + $('#files'+id+'progressBar').remove(); + } + + //Inform complete upload, destroy upload dialog, refresh file list + + $('div#pb_dialog').foundation('reveal', 'close') + return false; + }, + onCancel: function(id, fileName){ + } + }); + + var file_input = false; + uploader._button._options.onChange = function(input) { + file_input = input; return false; + }; + + $('#create_file_submit',dialog).click(function(){ + var upload = false; + + var ds_id = $('#file_datastore .resource_list_select',dialog).val(); + if (!ds_id){ + notifyError(tr("Please select a datastore for this file")); + return false; + }; + + var file_json = {}; + + var name = $('#file_name',dialog).val(); + file_json["NAME"] = name; + + var desc = $('#file_desc',dialog).val(); + if (desc.length){ + file_json["DESCRIPTION"] = desc; + } + + var type = $('#file_type',dialog).val(); + file_json["TYPE"]= type; + + + switch ($('#src_path_select input:checked',dialog).val()){ + case "path": + path = $('#file_path',dialog).val(); + if (path) file_json["PATH"] = path; + break; + case "upload": + upload=true; + break; + } + + file_obj = { "image" : file_json, + "ds_id" : ds_id}; + + //we this is an file upload we trigger FileUploader + //to start the upload + if (upload){ + $create_file_dialog.foundation('reveal', 'close'); + $create_file_dialog.empty(); + setupCreateFileDialog(); + + uploader._onInputChange(file_input); + } else { + Sunstone.runAction("File.create", file_obj); + }; + + return false; + }); + + $('#create_file_submit_manual',dialog).click(function(){ + var template=$('#template',dialog).val(); + var ds_id = $('#file_datastore_raw .resource_list_select',dialog).val(); + + if (!ds_id){ + notifyError(tr("Please select a datastore for this file")); + return false; + }; + + var file_obj = { + "image" : { + "image_raw" : template + }, + "ds_id" : ds_id + }; + Sunstone.runAction("File.create",file_obj); + return false; + }); + + setupTips(dialog); + + $('#wizard_file_reset_button', dialog).click(function(){ + $('#create_file_dialog').html(""); + setupCreateFileDialog(); + + popUpCreateFileDialog(); + }); + + $('#advanced_file_reset_button', dialog).click(function(){ + $('#create_file_dialog').html(""); + setupCreateFileDialog(); + + popUpCreateFileDialog(); + $("a[href='#file_manual']").click(); + }); +} + +function popUpCreateFileDialog(){ + $('#files_file-uploader input',$create_file_dialog).removeAttr("style"); + $('#files_file-uploader input',$create_file_dialog).attr('style','margin:0;width:256px!important'); + + var ds_id = $("div#file_datastore .resource_list_select", + $create_file_dialog).val(); + + var ds_id_raw = $("div#file_datastore_raw .resource_list_select", + $create_file_dialog).val(); + + // Filter out DS with type image (0) or system (1) + var filter_att = ["TYPE", "TYPE"]; + var filter_val = ["0", "1"]; + + insertSelectOptions('div#file_datastore', $create_file_dialog, "Datastore", + ds_id, false, null, filter_att, filter_val); + + insertSelectOptions('div#file_datastore_raw', $create_file_dialog, "Datastore", + ds_id_raw, false, null, filter_att, filter_val); + + $create_file_dialog.foundation().foundation('reveal', 'open'); + $("input#file_name",$create_file_dialog).focus(); +} + +function is_persistent_file(id){ + var data = getElementData(id,"#file",dataTable_files)[8]; + return $(data).is(':checked'); +}; + +//The DOM is ready at this point +$(document).ready(function(){ + var tab_name = 'files-tab'; + + if (Config.isTabEnabled(tab_name)) { + dataTable_files = $("#datatable_files",main_tabs_context).dataTable({ + "aoColumnDefs": [ + { "bSortable": false, "aTargets": ["check"] }, + { "sWidth": "35px", "aTargets": [0] }, + { "bVisible": true, "aTargets": Config.tabTableColumns(tab_name)}, + { "bVisible": false, "aTargets": ['_all']} + ], + "bSortClasses" : false, + "bDeferRender": true, + }); + + $('#file_search').keyup(function(){ + dataTable_files.fnFilter( $(this).val() ); + }) + + dataTable_files.on('draw', function(){ + recountCheckboxes(dataTable_files); + }) + + Sunstone.runAction("File.list"); + + setupCreateFileDialog(); + + initCheckAllBoxes(dataTable_files); + tableCheckboxesListener(dataTable_files); + infoListener(dataTable_files,'File.show'); + + $('div#files_tab div.legend_div').hide(); + dataTable_files.fnSort( [ [1,config['user_config']['table_order']] ] ); + } +}); diff --git a/bugfix/images-tab.js b/bugfix/images-tab.js new file mode 100644 index 0000000..fa6a4c1 --- /dev/null +++ b/bugfix/images-tab.js @@ -0,0 +1,1256 @@ +/* -------------------------------------------------------------------------- */ +/* 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("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']] ] ); + } +}); diff --git a/eole-one-frontend.mk b/eole-one-frontend.mk new file mode 100644 index 0000000..12f4bb6 --- /dev/null +++ b/eole-one-frontend.mk @@ -0,0 +1,2 @@ +bugfix_DATA_DIR := $(eole_DIR)/hapy/bugfix +