eole-one-frontend.mk: Création du script
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
This commit is contained in:
parent
38aa3c612b
commit
72892069ad
847
bugfix/files-tab.js
Normal file
847
bugfix/files-tab.js
Normal file
@ -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 ='<div class="row">\
|
||||
<div class="large-5 columns">\
|
||||
<h3 class="subheader">'+tr("Create File")+'</h3>'+
|
||||
'</div>'+
|
||||
'<div class="large-7 columns">'+
|
||||
'<dl class="tabs right" data-tab>\
|
||||
<dd class="active"><a href="#file_easyTab">'+tr("Wizard")+'</a></dd>\
|
||||
<dd><a href="#file_manualTab">'+tr("Advanced mode")+'</a></dd>\
|
||||
</dl>\
|
||||
</div>\
|
||||
</div>\
|
||||
<form id="create_file_form_easy" action="" class="custom creation">\
|
||||
<div class="tabs-content">\
|
||||
<div id="file_easyTab" class="content active">\
|
||||
<div class="row vm_param">\
|
||||
<div class="large-6 columns">\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="file_name">'+tr("Name")+
|
||||
'<span class="tip">'+tr("Name that the File will get. Every file must have a unique name.")+'</span>\
|
||||
</label>\
|
||||
<input type="text" name="file_name" id="file_name" />\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="file_desc">'+tr("Description")+
|
||||
'<span class="tip">'+tr("Human readable description of the file for other users.")+'</span>\
|
||||
</label>\
|
||||
<textarea name="file_desc" id="file_desc" rows="4"></textarea>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="large-6 columns">\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="file_type">'+tr("Type")+
|
||||
'<span class="tip">'+tr("Type of the file.")+'<br/><br/>'
|
||||
+ tr(" KERNEL & RAMDISK files can be used in the OS Booting section of the Template wizard.")+'<br/><br/>'
|
||||
+ tr(" CONTEXT files can be included in the context CD-ROM, from the Context/Files section of the Template wizard.")+
|
||||
'</span>'+
|
||||
'</label>\
|
||||
<select name="file_type" id="file_type">\
|
||||
<option value="KERNEL">'+tr("Kernel")+'</option>\
|
||||
<option value="RAMDISK">'+tr("Ramdisk")+'</option>\
|
||||
<option value="CONTEXT">'+tr("Context")+'</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="file_datastore">'+tr("Datastore")+
|
||||
'<span class="tip">'+tr("Select the datastore for this file")+'</span>'+
|
||||
'</label>\
|
||||
<div id="file_datastore" name="file_datastore">\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<fieldset>\
|
||||
<legend>'+tr("Image location")+':</legend>\
|
||||
<div class="row" id="src_path_select">\
|
||||
<div class="large-12 columns text-center">\
|
||||
<input type="radio" name="src_path" id="path_file" value="path"><label for="path_file">'+ tr("Provide a path")+'</label> \
|
||||
<input type="radio" name="src_path" id="upload_file" value="upload"> <label for="upload_file">'+tr("Upload")+'</label> \
|
||||
</div>\
|
||||
</div>\
|
||||
<br>\
|
||||
<div class="file_param row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="file_path">'+tr("Path")+
|
||||
'<span class="tip">'+tr("Path to the original file that will be copied to the file repository.")+'</span>'+
|
||||
'</label>\
|
||||
<input type="text" name="file_path" id="file_path" />\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div id="files_file-uploader" class="large-12 columns text-center">\
|
||||
</div>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button success radius right" id="create_file_submit" type="button" value="file/create">'+tr("Create")+'</button>\
|
||||
<button id="wizard_file_reset_button" class="button secondary radius" type="reset" value="reset">'+tr("Reset")+'</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div id="file_manualTab" class="content">\
|
||||
<div class="row">\
|
||||
<div class="columns large-12">\
|
||||
<label for="file_datastores_raw">'+tr("Datastore")+':</label>\
|
||||
<div id="file_datastore_raw" name="file_datastore_raw">\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="columns large-12">\
|
||||
<textarea id="template" rows="15" style="height:180px !important; width:100%;"></textarea>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button success radius right" id="create_file_submit_manual" value="file/create">'+tr("Create")+'</button>\
|
||||
<button id="advanced_file_reset_button" class="button secondary radius" type="reset" value="reset">'+tr("Reset")+'</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a class="close-reveal-modal">×</a>\
|
||||
</form>\
|
||||
</div>';
|
||||
|
||||
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: '<div class="large-12 columns">\
|
||||
<div id="files_upload_progress_bars"></div>\
|
||||
</div>',
|
||||
search_input: '<input id="file_search" type="text" placeholder="'+tr("Search")+'" />',
|
||||
list_header: '<i class="fa fa-fw fa-folder-open"></i> '+tr("Files & Kernels"),
|
||||
info_header: '<i class="fa fa-fw fa-folder-open"></i> '+tr("File"),
|
||||
subheader: '<span class="total_files"/> <small>'+tr("TOTAL")+'</small> \
|
||||
<span class="size_files"/> <small>'+tr("SIZE")+'</small>',
|
||||
table: '<table id="datatable_files" class="datatable twelve">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th class="check"><input type="checkbox" class="check_all" value=""></input></th>\
|
||||
<th>'+tr("ID")+'</th>\
|
||||
<th>'+tr("Owner")+'</th>\
|
||||
<th>'+tr("Group")+'</th>\
|
||||
<th>'+tr("Name")+'</th>\
|
||||
<th>'+tr("Datastore")+'</th>\
|
||||
<th>'+tr("Size")+'</th>\
|
||||
<th>'+tr("Type")+'</th>\
|
||||
<th>'+tr("Registration time")+'</th>\
|
||||
<th>'+tr("Persistent")+'</th>\
|
||||
<th>'+tr("Status")+'</th>\
|
||||
<th>'+tr("#VMS")+'</th>\
|
||||
<th>'+tr("Target")+'</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="tbodyfiles">\
|
||||
</tbody>\
|
||||
</table>'
|
||||
}
|
||||
|
||||
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 [
|
||||
'<input class="check_item" type="checkbox" id="file_'+file.ID+'" name="selected_items" value="'+file.ID+'"/>',
|
||||
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:
|
||||
'<div class="row">\
|
||||
<div class="large-6 columns">\
|
||||
<table id="info_file_table" class="dataTable extended_table">\
|
||||
<thead>\
|
||||
<tr><th colspan="3">'+tr("File")+' - '+file_info.NAME+'</th></tr>\
|
||||
</thead>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("ID")+'</td>\
|
||||
<td class="value_td">'+file_info.ID+'</td>\
|
||||
<td></td>\
|
||||
</tr>'+
|
||||
insert_rename_tr(
|
||||
'files-tab',
|
||||
"File",
|
||||
file_info.ID,
|
||||
file_info.NAME)+
|
||||
'<tr>\
|
||||
<td class="key_td">'+tr("Datastore")+'</td>\
|
||||
<td class="value_td">'+file_info.DATASTORE+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Type")+'</td>\
|
||||
<td class="value_td_type_files">'+OpenNebula.Helper.image_type(file_info.TYPE)+'</td>\
|
||||
<td><div id="div_edit_chg_type_files">\
|
||||
<a id="div_edit_chg_type_files_link" class="edit_e" href="#"><i class="fa fa-pencil-square-o right"/></a>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Register time")+'</td>\
|
||||
<td class="value_td">'+pretty_time(file_info.REGTIME)+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Filesystem type")+'</td>\
|
||||
<td class="value_td">'+(typeof file_info.FSTYPE === "string" ? file_info.FSTYPE : "--")+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Size")+'</td>\
|
||||
<td class="value_td">'+humanize_size_from_mb(file_info.SIZE)+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("State")+'</td>\
|
||||
<td class="value_td">'+OpenNebula.Helper.resource_state("file",file_info.STATE)+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Running VMS")+'</td>\
|
||||
<td class="value_td">'+file_info.RUNNING_VMS+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
<div class="large-6 columns">' +
|
||||
insert_permissions_table('files-tab',
|
||||
"File",
|
||||
file_info.ID,
|
||||
file_info.UNAME,
|
||||
file_info.GNAME,
|
||||
file_info.UID,
|
||||
file_info.GID) +
|
||||
'</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-9 columns">'+
|
||||
insert_extended_template_table(file_info.TEMPLATE,
|
||||
"File",
|
||||
file_info.ID,
|
||||
"Attributes") +
|
||||
'</div>\
|
||||
</div>'
|
||||
}
|
||||
|
||||
$("#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(
|
||||
'<select id="chg_type_select_files">\
|
||||
<option value="KERNEL">KERNEL</option>\
|
||||
<option value="RAMDISK">RAMDISK</option>\
|
||||
<option value="CONTEXT">CONTEXT</option>\
|
||||
</select>');
|
||||
|
||||
$('#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('<div id="create_file_dialog"></div>');
|
||||
$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('<div id="files'+id+'progressBar" class="row" style="margin-bottom:10px">\
|
||||
<div class="large-2 columns dataTables_info">\
|
||||
'+tr("Uploading...")+'\
|
||||
</div>\
|
||||
<div class="large-10 columns">\
|
||||
<div id="upload_progress_container" class="progress nine radius" style="height:25px !important">\
|
||||
<span class="meter" style="width:0%"></span>\
|
||||
</div>\
|
||||
<div class="progress-text" style="margin-left:15px">'+id+' '+fileName+'</div>\
|
||||
</div>\
|
||||
</div>');
|
||||
|
||||
$('#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']] ] );
|
||||
}
|
||||
});
|
1256
bugfix/images-tab.js
Normal file
1256
bugfix/images-tab.js
Normal file
@ -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 ='<div class="row create_image_header">\
|
||||
<div class="large-5 columns">\
|
||||
<h3 class="subheader">'+tr("Create Image")+'</h3>'+
|
||||
'</div>'+
|
||||
'<div class="large-7 columns">'+
|
||||
'<dl class="tabs right" data-tab>\
|
||||
<dd class="active"><a href="#img_easyTab">'+tr("Wizard")+'</a></dd>\
|
||||
<dd><a href="#img_manualTab">'+tr("Advanced mode")+'</a></dd>\
|
||||
</dl>\
|
||||
</div>\
|
||||
</div>\
|
||||
<form id="create_image" action="" class="custom creation">\
|
||||
<div class="tabs-content">\
|
||||
<div id="img_easyTab" class="content active">\
|
||||
<div class="row vm_param">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="img_name">'+tr("Name")+
|
||||
'<span class="tip">'+tr("Name that the Image will get. Every image must have a unique name.")+'</span>\
|
||||
</label>\
|
||||
<input type="text" name="img_name" id="img_name" />\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="img_desc">'+tr("Description")+
|
||||
'<span class="tip">'+tr("Human readable description of the image for other users.")+'</span>\
|
||||
</label>\
|
||||
<textarea name="img_desc" id="img_desc" rows="4"></textarea>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-6 columns">\
|
||||
<label for="img_type">'+tr("Type")+
|
||||
'<span class="tip">'+tr("Type of the image.")+'<br/><br/>'
|
||||
+ tr(" OS images contain a working operative system.")+'<br/><br/>'
|
||||
+ tr(" CDROM images are readonly data.")+'<br/><br/>'
|
||||
+ tr(" DATABLOCK images are a storage for data. They can be created from previous existing data, or as an empty drive.")+
|
||||
'</span>'+
|
||||
'</label>\
|
||||
<select name="img_type" id="img_type">\
|
||||
<option value="OS">'+tr("OS")+'</option>\
|
||||
<option value="CDROM">'+tr("CDROM")+'</option>\
|
||||
<option value="DATABLOCK">'+tr("DATABLOCK")+'</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
<div class="large-6 columns">\
|
||||
<label for="img_datastore">'+tr("Datastore")+
|
||||
'<span class="tip">'+tr("Select the datastore for this image")+'</span>'+
|
||||
'</label>\
|
||||
<div id="img_datastore" name="img_datastore">\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="large-6 columns">\
|
||||
<input type="checkbox" id="img_persistent" name="img_persistent" value="YES" />\
|
||||
<label for="img_persistent">'+tr("Persistent")+
|
||||
'<span class="tip">'+tr("Persistence of the image")+'</span>'+
|
||||
'</label>\
|
||||
</div>\
|
||||
</div>\
|
||||
<br>\
|
||||
<fieldset>\
|
||||
<legend>'+tr("Image location")+':</legend>\
|
||||
<div class="row" id="src_path_select">\
|
||||
<div class="large-12 columns text-center">\
|
||||
<input type="radio" name="src_path" id="path_image" value="path"><label for="path_image">'+ tr("Provide a path")+'</label> \
|
||||
<input type="radio" name="src_path" id="upload_image" value="upload"> <label for="upload_image">'+tr("Upload")+'</label> \
|
||||
<input type="radio" name="src_path" id="datablock_img" value="datablock" disabled> <label for="datablock_img">'+tr("Empty datablock")+'</label> \
|
||||
</div>\
|
||||
</div>\
|
||||
<br>\
|
||||
<div class="img_param row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="img_path">'+tr("Path")+
|
||||
'<span class="tip">'+tr("Path to the original file that will be copied to the image repository. If not specified for a DATABLOCK type image, an empty image will be created.")+'</span>'+
|
||||
'</label>\
|
||||
<input type="text" name="img_path" id="img_path" />\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div id="file-uploader" class="large-12 columns text-center">\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="img_size row">\
|
||||
<div class="large-6 columns">\
|
||||
<label for="img_size">'+tr("Size")+
|
||||
'<span class="tip">'+tr("Size of the datablock in MB.")+'</span>'+
|
||||
'</label>\
|
||||
<input type="text" name="img_size" id="img_size" />\
|
||||
</div>\
|
||||
<div class="large-6 columns">\
|
||||
<label for="img_fstype">'+tr("FS type")+
|
||||
'<span class="tip">'+tr("Type of file system to be built.")+'<br><br>'
|
||||
+ tr(" Plain. When the disk image is used directly by the hypervisor we can format the image, and so it is ready to be used by the guest OS. Values: ext2, ext3, ext4, ntfs, reiserfs, jfs, swap. Any other fs supported by mkfs will work if no special option is needed.")+'<br><br>'
|
||||
+ tr(" Formatted. The disk image is stored in a hypervisor specific format VMDK or Qcow2. Then we cannot really make a filesystem on the image, just create the device and let the guest OS format the disk. Use raw to not to format the new image. Values: raw, qcow2, vmdk_*.")+
|
||||
'</span>'+
|
||||
'</label>\
|
||||
<input type="text" name="img_fstype" id="img_fstype" />\
|
||||
</div>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<div class="show_hide" id="advanced_image_create">\
|
||||
<h4><small><i class=" fa fa-caret-down"/> '+tr("Advanced options")+'<a id="add_os_boot_opts" class="icon_left" href="#"></a></small></h4>\
|
||||
</div>\
|
||||
<div class="advanced">\
|
||||
<div class="row">\
|
||||
<div class="large-6 columns">\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="img_dev_prefix">'+tr("Device prefix")+
|
||||
'<span class="tip">'+tr("Prefix for the emulated device this image will be mounted at. For instance, “hd”, “sd”. If omitted, the default value is the one defined in oned.conf (installation default is “hd”).")+'</span>'+
|
||||
'</label>\
|
||||
<input type="text" name="img_dev_prefix" id="img_dev_prefix" />\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="img_driver">'+tr("Driver")+
|
||||
'<span class="tip">'+tr("Specific image mapping driver. KVM: raw, qcow2. XEN: tap:aio, file:")+'</span>'+
|
||||
'</label>\
|
||||
<input type="text" name="img_driver" id="img_driver" />\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="large-6 columns">\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="img_target">'+tr("Target")+
|
||||
'<span class="tip">'+tr("Target on which the image will be mounted at. For example: hda, sdb...")+'</span>'+
|
||||
'</label>\
|
||||
<input type="text" name="img_target" id="img_target" />\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<br>\
|
||||
<div class="row">\
|
||||
<fieldset>\
|
||||
<legend>' + tr("Custom attributes") + '</legend>\
|
||||
<div class="row">\
|
||||
<div class="large-6 columns">\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="custom_var_image_name">'+tr("Name")+'</label>\
|
||||
<input type="text" id="custom_var_image_name" name="custom_var_image_name" />\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<label for="custom_var_image_value">'+tr("Value")+'</label>\
|
||||
<input type="text" id="custom_var_image_value" name="custom_var_image_value" />\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<button class="add_remove_button add_button secondary button small radius" id="add_custom_var_image_button" value="add_custom_image_var">\
|
||||
'+tr("Add")+'\
|
||||
</button>\
|
||||
<button class="add_remove_button secondary button small radius" id="remove_custom_var_image_button" value="remove_custom_image_var">\
|
||||
'+tr("Remove selected")+'\
|
||||
</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="large-6 columns">\
|
||||
<div class="row">\
|
||||
<div class="eight centered columns">\
|
||||
<select id="custom_var_image_box" name="custom_var_image_box" style="height:180px !important; width:100%" multiple>\
|
||||
<!-- insert leases -->\
|
||||
</select>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button success radius right" id="create_image_submit" type="button" value="image/create">'+tr("Create")+'</button>\
|
||||
<button id="wizard_image_reset_button" class="button secondary radius" type="reset" value="reset">'+tr("Reset")+'</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div id="img_manualTab" class="content">\
|
||||
<div class="row">\
|
||||
<div class="columns large-12">\
|
||||
<label for="img_datastores_raw">'+tr("Datastore")+':</label>\
|
||||
<div id="img_datastore_raw" name="img_datastore_raw">\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="columns large-12">\
|
||||
<textarea id="template" rows="15" style="height:380px !important; width:100%;"></textarea>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button success radius right" id="create_image_submit_manual" value="image/create">'+tr("Create")+'</button>\
|
||||
<button id="advanced_image_reset_button" class="button secondary radius" type="reset" value="reset">'+tr("Reset")+'</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a class="close-reveal-modal">×</a>\
|
||||
</form>\
|
||||
</div>';
|
||||
|
||||
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: '<div class="large-12 columns">\
|
||||
<div id="upload_progress_bars"></div>\
|
||||
</div>',
|
||||
search_input: '<input id="image_search" type="text" placeholder="'+tr("Search")+'" />',
|
||||
list_header: '<i class="fa fa-fw fa-upload"></i> '+tr("Images"),
|
||||
info_header: '<i class="fa fa-fw fa-upload"></i> '+tr("Image"),
|
||||
subheader: '<span class="total_images"/> <small>'+tr("TOTAL")+'</small> \
|
||||
<span class="size_images"/> <small>'+tr("USED")+'</small>',
|
||||
table: '<table id="datatable_images" class="datatable twelve">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th class="check"><input type="checkbox" class="check_all" value=""></input></th>\
|
||||
<th>'+tr("ID")+'</th>\
|
||||
<th>'+tr("Owner")+'</th>\
|
||||
<th>'+tr("Group")+'</th>\
|
||||
<th>'+tr("Name")+'</th>\
|
||||
<th>'+tr("Datastore")+'</th>\
|
||||
<th>'+tr("Size")+'</th>\
|
||||
<th>'+tr("Type")+'</th>\
|
||||
<th>'+tr("Registration time")+'</th>\
|
||||
<th>'+tr("Persistent")+'</th>\
|
||||
<th>'+tr("Status")+'</th>\
|
||||
<th>'+tr("#VMS")+'</th>\
|
||||
<th>'+tr("Target")+'</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="tbodyimages">\
|
||||
</tbody>\
|
||||
</table>'
|
||||
}
|
||||
|
||||
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 [
|
||||
'<input class="check_item" type="checkbox" id="image_'+image.ID+'" name="selected_items" value="'+image.ID+'"/>',
|
||||
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:
|
||||
'<div class="row">\
|
||||
<div class="large-6 columns">\
|
||||
<table id="info_img_table" class="dataTable extended_table">\
|
||||
<thead>\
|
||||
<tr><th colspan="3">'+tr("Information")+'</th></tr>\
|
||||
</thead>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("ID")+'</td>\
|
||||
<td class="value_td">'+img_info.ID+'</td>\
|
||||
<td></td>\
|
||||
</tr>'+
|
||||
insert_rename_tr(
|
||||
'images-tab',
|
||||
"Image",
|
||||
img_info.ID,
|
||||
img_info.NAME)+
|
||||
'<tr>\
|
||||
<td class="key_td">'+tr("Datastore")+'</td>\
|
||||
<td class="value_td">'+img_info.DATASTORE+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Type")+'</td>\
|
||||
<td class="value_td_type">'+OpenNebula.Helper.image_type(img_info.TYPE)+'</td>\
|
||||
<td><div id="div_edit_chg_type">\
|
||||
<a id="div_edit_chg_type_link" class="edit_e" href="#"><i class="fa fa-pencil-square-o right"/></a>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Register time")+'</td>\
|
||||
<td class="value_td">'+pretty_time(img_info.REGTIME)+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Persistent")+'</td>\
|
||||
<td class="value_td_persistency">'+(parseInt(img_info.PERSISTENT) ? tr("yes") : tr("no"))+'</td>\
|
||||
<td><div id="div_edit_persistency">\
|
||||
<a id="div_edit_persistency_link" class="edit_e" href="#"><i class="fa fa-pencil-square-o right"/></a>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Filesystem type")+'</td>\
|
||||
<td class="value_td">'+(typeof img_info.FSTYPE === "string" ? img_info.FSTYPE : "--")+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Size")+'</td>\
|
||||
<td class="value_td">'+humanize_size_from_mb(img_info.SIZE)+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("State")+'</td>\
|
||||
<td class="value_td">'+OpenNebula.Helper.resource_state("image",img_info.STATE)+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Running VMS")+'</td>\
|
||||
<td class="value_td">'+img_info.RUNNING_VMS+'</td>\
|
||||
<td></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
<div class="large-6 columns">' +
|
||||
insert_permissions_table('images-tab',
|
||||
"Image",
|
||||
img_info.ID,
|
||||
img_info.UNAME,
|
||||
img_info.GNAME,
|
||||
img_info.UID,
|
||||
img_info.GID) +
|
||||
'</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-9 columns">'+
|
||||
insert_extended_template_table(img_info.TEMPLATE,
|
||||
"Image",
|
||||
img_info.ID,
|
||||
"Attributes") +
|
||||
'</div>\
|
||||
</div>'
|
||||
}
|
||||
|
||||
$("#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(
|
||||
'<select id="chg_type_select">\
|
||||
<option value="OS">OS</option>\
|
||||
<option value="CDROM">CDROM</option>\
|
||||
<option value="DATABLOCK">DATABLOCK</option>\
|
||||
</select>');
|
||||
|
||||
$('#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(
|
||||
'<select id="persistency_select">\
|
||||
<option value="yes">'+tr("yes")+'</option>\
|
||||
<option value="no">'+tr("no")+'</option>\
|
||||
</select>');
|
||||
|
||||
$('#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 : '<div id="datatable_image_vms_info_div" class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<table id="datatable_image_vms" class="datatable twelve">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th class="check"><input type="checkbox" class="check_all" value=""></input></th>\
|
||||
<th>'+tr("ID")+'</th>\
|
||||
<th>'+tr("Owner")+'</th>\
|
||||
<th>'+tr("Group")+'</th>\
|
||||
<th>'+tr("Name")+'</th>\
|
||||
<th>'+tr("Status")+'</th>\
|
||||
<th>'+tr("Used CPU")+'</th>\
|
||||
<th>'+tr("Used Memory")+'</th>\
|
||||
<th>'+tr("Host")+'</th>\
|
||||
<th>'+tr("IPs")+'</th>\
|
||||
<th>'+tr("Start Time")+'</th>\
|
||||
<th>'+tr("VNC")+'</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="tbody_image_vmachines">\
|
||||
</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>'
|
||||
}
|
||||
|
||||
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('<div id="create_image_dialog"></div>');
|
||||
}
|
||||
|
||||
$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= '<option value=\''+value+'\' name=\''+name+'\'>'+
|
||||
name+'='+value+
|
||||
'</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('<div id="'+id+'progressBar" class="row" style="margin-bottom:10px">\
|
||||
<div class="large-2 columns dataTables_info">\
|
||||
'+tr("Uploading...")+'\
|
||||
</div>\
|
||||
<div class="large-10 columns">\
|
||||
<div id="upload_progress_container" class="progress nine radius" style="height:25px !important">\
|
||||
<span class="meter" style="width:0%"></span>\
|
||||
</div>\
|
||||
<div class="progress-text" style="margin-left:15px">'+id+' '+fileName+'</div>\
|
||||
</div>\
|
||||
</div>');
|
||||
},
|
||||
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('<div id="image_clone_dialog"></div>');
|
||||
var dialog = $('#image_clone_dialog',dialogs_context);
|
||||
|
||||
//Put HTML in place
|
||||
|
||||
var html = '<div class="row">\
|
||||
<h3 id="create_vnet_header" class="subheader">'+tr("Clone Image")+'</h3>\
|
||||
</div>\
|
||||
<form>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns">\
|
||||
<div class="clone_one"></div>\
|
||||
<div class="clone_several">'+tr("Several image are selected, please choose prefix to name the new copies")+':</div>\
|
||||
<br>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="columns large-12">\
|
||||
<label class="clone_one">'+tr("Name")+':</label>\
|
||||
<label class="clone_several">'+tr("Prefix")+':</label>\
|
||||
<input type="text" name="name"></input>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="form_buttons row">\
|
||||
<button class="button radius right" id="image_clone_button" value="Image.clone">'+tr("Clone")+'</button>\
|
||||
</div>\
|
||||
<a class="close-reveal-modal">×</a>\
|
||||
</form>\
|
||||
';
|
||||
|
||||
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']] ] );
|
||||
}
|
||||
});
|
2
eole-one-frontend.mk
Normal file
2
eole-one-frontend.mk
Normal file
@ -0,0 +1,2 @@
|
||||
bugfix_DATA_DIR := $(eole_DIR)/hapy/bugfix
|
||||
|
Loading…
Reference in New Issue
Block a user