From 72892069ada70c1976526e3d7f6205c4268115d5 Mon Sep 17 00:00:00 2001 From: Philippe Caseiro Date: Thu, 9 Oct 2014 16:12:24 +0200 Subject: [PATCH] =?UTF-8?q?eole-one-frontend.mk:=20Cr=C3=A9ation=20du=20sc?= =?UTF-8?q?ript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bugfix/files-tab.js: Ajout du fichier bugfix/files-tab.js Ajout du fichier Ce bug est connus pour la version 4.6.2, (http://docs.opennebula.org/4.6/release_notes/release_notes/known_issues.html) "#2984 Image and file upload from sunstone is broken. To fix it, download these versions of the scripts from the repo as root, restart sunstone and clear the cache of the browser" ref #9211 @10m --- bugfix/files-tab.js | 847 ++++++++++++++++++++++++++++ bugfix/images-tab.js | 1256 ++++++++++++++++++++++++++++++++++++++++++ eole-one-frontend.mk | 2 + 3 files changed, 2105 insertions(+) create mode 100644 bugfix/files-tab.js create mode 100644 bugfix/images-tab.js create mode 100644 eole-one-frontend.mk 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("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 +