diff --git a/src/sunstone/etc/sunstone-views/kvm/admin.yaml b/src/sunstone/etc/sunstone-views/kvm/admin.yaml index 2fab7200db..f0d13712bb 100644 --- a/src/sunstone/etc/sunstone-views/kvm/admin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/admin.yaml @@ -634,6 +634,9 @@ tabs: image_info_tab: true image_vms_tab: true image_snapshots_tab: true + template_creation_tabs: + image: true + docker: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml index 409acc2b02..88c4432276 100644 --- a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml @@ -634,6 +634,9 @@ tabs: image_info_tab: true image_vms_tab: true image_snapshots_tab: true + template_creation_tabs: + image: true + docker: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/kvm/user.yaml b/src/sunstone/etc/sunstone-views/kvm/user.yaml index 84e28d6453..0a6c182ea4 100644 --- a/src/sunstone/etc/sunstone-views/kvm/user.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/user.yaml @@ -627,6 +627,9 @@ tabs: image_info_tab: true image_vms_tab: true image_snapshots_tab: true + template_creation_tabs: + image: true + docker: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/mixed/admin.yaml b/src/sunstone/etc/sunstone-views/mixed/admin.yaml index 9bdcaae7c5..1eb3824f82 100644 --- a/src/sunstone/etc/sunstone-views/mixed/admin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/admin.yaml @@ -636,6 +636,9 @@ tabs: image_info_tab: true image_vms_tab: true image_snapshots_tab: true + template_creation_tabs: + image: true + docker: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml index e14fe88840..32c56c65d4 100644 --- a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml @@ -635,6 +635,9 @@ tabs: image_info_tab: true image_vms_tab: true image_snapshots_tab: true + template_creation_tabs: + image: true + docker: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/etc/sunstone-views/mixed/user.yaml b/src/sunstone/etc/sunstone-views/mixed/user.yaml index ba18b910a7..45966311be 100644 --- a/src/sunstone/etc/sunstone-views/mixed/user.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/user.yaml @@ -628,6 +628,9 @@ tabs: image_info_tab: true image_vms_tab: true image_snapshots_tab: true + template_creation_tabs: + image: true + docker: true table_columns: - 0 # Checkbox - 1 # ID diff --git a/src/sunstone/public/app/main.js b/src/sunstone/public/app/main.js index b10632965d..2d3016ca2e 100644 --- a/src/sunstone/public/app/main.js +++ b/src/sunstone/public/app/main.js @@ -43,7 +43,7 @@ require.config({ /* Foundation */ "foundation": "../bower_components/foundation-sites/dist/foundation", - + /* Handlebars */ "hbs": "../bower_components/require-handlebars-plugin/hbs", @@ -102,7 +102,10 @@ require.config({ "sprintf": "../bower_components/sprintf/dist/sprintf.min", /* socket.io-client */ - "socket-io-client": "../bower_components/socket.io-client/dist/socket.io.slim" + "socket-io-client": "../bower_components/socket.io-client/dist/socket.io.slim", + + /* ace editor */ + "ace-builds": "../bower_components/ace-builds/ace" }, shim: { /* Tabs */ diff --git a/src/sunstone/public/app/tabs/files-tab/actions.js b/src/sunstone/public/app/tabs/files-tab/actions.js index 8ad53795a7..eeb6dda3cf 100644 --- a/src/sunstone/public/app/tabs/files-tab/actions.js +++ b/src/sunstone/public/app/tabs/files-tab/actions.js @@ -15,16 +15,16 @@ /* -------------------------------------------------------------------------- */ define(function(require) { - var Sunstone = require('sunstone'); - var Notifier = require('utils/notifier'); - var Locale = require('utils/locale'); - var OpenNebulaResource = require('opennebula/image'); - var CommonActions = require('utils/common-actions'); + var Sunstone = require("sunstone"); + var Notifier = require("utils/notifier"); + var Locale = require("utils/locale"); + var OpenNebulaResource = require("opennebula/image"); + var CommonActions = require("utils/common-actions"); var RESOURCE = "File"; var XML_ROOT = "IMAGE"; - var TAB_ID = require('./tabId'); - var CREATE_DIALOG_ID = require('./form-panels/create/formPanelId'); + var TAB_ID = require("./tabId"); + var CREATE_DIALOG_ID = require("./form-panels/create/formPanelId"); var _commonActions = new CommonActions(OpenNebulaResource, RESOURCE, TAB_ID, XML_ROOT, Locale.tr("File created")); @@ -38,13 +38,13 @@ define(function(require) { "File.delete" : _commonActions.del(), "File.update_template" : _commonActions.updateTemplate(), "File.append_template" : _commonActions.appendTemplate(), - "File.chown": _commonActions.multipleAction('chown'), - "File.chgrp": _commonActions.multipleAction('chgrp'), - "File.chmod": _commonActions.singleAction('chmod'), - "File.rename": _commonActions.singleAction('rename'), - "File.enable": _commonActions.multipleAction('enable'), - "File.disable": _commonActions.multipleAction('disable'), - "File.chtype": _commonActions.singleAction('chtype') + "File.chown": _commonActions.multipleAction("chown"), + "File.chgrp": _commonActions.multipleAction("chgrp"), + "File.chmod": _commonActions.singleAction("chmod"), + "File.rename": _commonActions.singleAction("rename"), + "File.enable": _commonActions.multipleAction("enable"), + "File.disable": _commonActions.multipleAction("disable"), + "File.chtype": _commonActions.singleAction("chtype") }; return _actions; diff --git a/src/sunstone/public/app/tabs/files-tab/buttons.js b/src/sunstone/public/app/tabs/files-tab/buttons.js index 86f953e1f3..595c65494c 100644 --- a/src/sunstone/public/app/tabs/files-tab/buttons.js +++ b/src/sunstone/public/app/tabs/files-tab/buttons.js @@ -15,7 +15,7 @@ /* -------------------------------------------------------------------------- */ define(function(require) { - var ImageButtons = require('tabs/images-tab/buttons'); + var ImageButtons = require("tabs/images-tab/buttons"); var Buttons = { "File.refresh" : ImageButtons["Image.refresh"], diff --git a/src/sunstone/public/app/tabs/files-tab/datatable.js b/src/sunstone/public/app/tabs/files-tab/datatable.js index 67b2987d29..c220a2228c 100644 --- a/src/sunstone/public/app/tabs/files-tab/datatable.js +++ b/src/sunstone/public/app/tabs/files-tab/datatable.js @@ -19,18 +19,18 @@ define(function(require) { DEPENDENCIES */ - var ImageCommonDataTable = require('tabs/images-tab/datatable-common'); + var ImageCommonDataTable = require("tabs/images-tab/datatable-common"); - var Locale = require('utils/locale'); - var Humanize = require('utils/humanize'); - var OpenNebulaImage = require('opennebula/image'); + var Locale = require("utils/locale"); + var Humanize = require("utils/humanize"); + var OpenNebulaImage = require("opennebula/image"); /* CONSTANTS */ var RESOURCE = "File"; - var TAB_NAME = require('./tabId'); + var TAB_NAME = require("./tabId"); /* CONSTRUCTOR diff --git a/src/sunstone/public/app/tabs/files-tab/form-panels/create-common.js b/src/sunstone/public/app/tabs/files-tab/form-panels/create-common.js new file mode 100644 index 0000000000..9760a123a2 --- /dev/null +++ b/src/sunstone/public/app/tabs/files-tab/form-panels/create-common.js @@ -0,0 +1,530 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +define(function(require) { + /* + DEPENDENCIES + */ + + var BaseFormPanel = require("utils/form-panels/form-panel"); + var Resumable = require("resumable"); + var Sunstone = require("sunstone"); + var OpenNebulaError = require("opennebula/error"); + var Notifier = require("utils/notifier"); + var Locale = require("utils/locale"); + var Tips = require("utils/tips"); + var OpenNebulaDatastore = require("opennebula/datastore"); + var ResourceSelect = require("utils/resource-select"); + var CustomTagsTable = require("utils/custom-tags-table"); + var BrowserInfo = require("utils/browser-info"); + var Config = require("sunstone-config"); + var WizardFields = require("utils/wizard-fields"); + var ProgressBar = require("utils/progress-bar"); + var Humanize = require("utils/humanize"); + + var TemplateWizardHTML = require("hbs!./create/wizard"); + var TemplateAdvancedHTML = require("hbs!./create/advanced"); + + /* + CONSTANTS + */ + var prepend = "file"; + + /* + CONSTRUCTOR + */ + + function FormPanel() { + var title = Locale.tr("Create File"); + + this.actions = { + "create": { + "title": title, + "buttonText": Locale.tr("Create"), + "resetButton": true + } + }; + + BaseFormPanel.call(this); + } + + FormPanel.prototype = Object.create(BaseFormPanel.prototype); + FormPanel.prototype.constructor = FormPanel; + FormPanel.prototype.htmlWizard = _htmlWizard; + FormPanel.prototype.htmlAdvanced = _htmlAdvanced; + FormPanel.prototype.submitWizard = _submitWizard; + FormPanel.prototype.submitAdvanced = _submitAdvanced; + FormPanel.prototype.onShow = _onShow; + FormPanel.prototype.setup = _setup; + + return FormPanel; + + + /* + FUNCTION DEFINITIONS + */ + + function _htmlWizard() { + return TemplateWizardHTML({ + "prepend": prepend, + "formPanelId": this.formPanelId, + "customTagsHTML": CustomTagsTable.html() + }); + } + + function _htmlAdvanced() { + return TemplateAdvancedHTML({ + "prepend": prepend, + formPanelId: this.formPanelId + }); + } + + function _onShow(context) { + $("#"+prepend+"_driver").val(""); + $("#"+prepend+"_name", context).focus(); + + var ds_id = $("#"+prepend+"_datastore .resource_list_select", context).val(); + var ds_id_raw = $("#"+prepend+"_datastore_raw .resource_list_select", context).val(); + + var filterValue = "" + OpenNebulaDatastore.TYPES.FILE_DS; + + ResourceSelect.insert({ + context: $("#"+prepend+"_datastore", context), + resourceName: "Datastore", + initValue: ds_id, + filterKey: "TYPE", + filterValue: filterValue, + triggerChange: true + }); + + ResourceSelect.insert({ + context: $("#"+prepend+"_datastore_raw", context), + resourceName: "Datastore", + initValue: ds_id_raw, + filterKey: "TYPE", + filterValue: filterValue, + triggerChange: true + }); + + return false; + } + + + function _setup(context) { + var that = this; + Tips.setup(context); + + $("select#"+prepend+"_type", context).change(function() { + var value = $(this).val(); + switch (value){ + case "DATABLOCK": + case "OS": + $("#datablock_img", context).removeAttr("disabled"); + break; + default: + $("#datablock_img", context).attr("disabled", "disabled"); + $("#path_image", context).click(); + } + }); + if(config["federation_mode"] == "SLAVE"){ + $("#upload_image").attr("disabled", "disabled"); + } + + $("#"+prepend+"_datastore", context).off("change", ".resource_list_select"); + $("#"+prepend+"_datastore", context).on("change", ".resource_list_select", function() { + var ds_id = $(this).val(); + OpenNebulaDatastore.show({ + data : { + id: ds_id + }, + timeout: true, + success: function(request, ds){ + var mad = ds["DATASTORE"]["DS_MAD"]; + var tm_mad = ds["DATASTORE"]["TM_MAD"]; + + var pers_forced = false; + + // Set the persistency + if (Config.onedConf.DS_MAD_CONF !== undefined) { + $.each(Config.onedConf.DS_MAD_CONF, function(i,e){ + if (e["NAME"] == mad && !$.isEmptyObject(e["PERSISTENT_ONLY"])) { + if (e["PERSISTENT_ONLY"] != undefined && + e["PERSISTENT_ONLY"].toLowerCase() == "yes") { + $("#"+prepend+"_persistent", context).prop("disabled", true); + $("#"+prepend+"_persistent", context).val("YES"); + pers_forced = true; + return false; + } + } + } + ); + } + + if (!pers_forced) { + $("#"+prepend+"_persistent", context).prop("disabled", false); + } + + // Display adequate values in the dialog. + switch (mad) { + case "vcenter": + $(".only_vcenter").show(); + $(".not_vcenter").hide(); + break; + default: + $(".only_vcenter").hide(); + $(".not_vcenter").show(); + } + + // Fill in the default driver + if (tm_mad == "qcow2"){ + $("select#"+prepend+"_driver",context).val("qcow2"); + } else { + //$("select#img_driver",context).val("raw"); + } + }, + error: function(request, error_json, container){ + Notifier.onError(request, error_json, container); + } + }); + }); + + // Custom Adapter Type + var custom_attrs = [ + "vcenter_adapter_type", + "vcenter_disk_type", + "img_dev_prefix", + "img_driver" + ]; + + $(custom_attrs).each(function(_, field) { + $("input[name=\"custom_"+field+"\"]",context).parent().hide(); + + $("select#"+field, context).on("change", function() { + var field = $(this).attr("name"); + + if ($(this).val() == "custom"){ + $("input[name=\"custom_"+field+"\"]",context).parent().show(); + $("input[name=\"custom_"+field+"\"]",context).attr("required", ""); + } else { + $("input[name=\"custom_"+field+"\"]",context).parent().hide(); + $("input[name=\"custom_"+field+"\"]",context).removeAttr("required"); + } + }); + }); + + $("#"+prepend+"_path,#"+prepend+"_size,#file-uploader", context).closest(".row").hide(); + $("input[name='src_path']", context).change(function() { + var value = $(this).val(); + switch (value){ + case "path": + $("#"+prepend+"_size,#file-uploader", context).closest(".row").hide(); + $("#"+prepend+"_path", context).closest(".row").show(); + $("#"+prepend+"_path", context).attr("required", ""); + $("#"+prepend+"_size", context).removeAttr("required"); + $(".datablock-input, .upload-input").addClass("hide"); + $(".path-input").removeClass("hide"); + $("#"+prepend+"_driver").val(""); + break; + case "datablock": + $("#"+prepend+"_path,#file-uploader", context).closest(".row").hide(); + $("#"+prepend+"_size", context).closest(".row").show(); + $("#"+prepend+"_path", context).removeAttr("required"); + $("#"+prepend+"_size", context).attr("required", ""); + $(".path-input, .upload-input").addClass("hide"); + $(".datablock-input").removeClass("hide"); + break; + case "upload": + $("#"+prepend+"_path,#"+prepend+"_size", context).closest(".row").hide(); + $("#file-uploader", context).closest(".row").show(); + $("#"+prepend+"_path", context).removeAttr("required"); + $("#"+prepend+"_size", context).removeAttr("required"); + $(".path-input, .datablock-input").addClass("hide"); + $(".upload-input").removeClass("hide"); + $("#"+prepend+"_driver").val(""); + break; + } + }); + + $("#img_type", context).change(function() { + var value = $(this).val(); + if(value == "CDROM") + $("#"+prepend+"_persistent", context).closest(".row").hide(); + else + $("#"+prepend+"_persistent", context).closest(".row").show(); + }); + + $("#path_image", context).click(); + + CustomTagsTable.setup(context); + + if (BrowserInfo.getInternetExplorerVersion() > -1) { + $("#upload_image").attr("disabled", "disabled"); + } else { + that.uploader = new Resumable({ + target: "upload_chunk", + chunkSize: 10 * 1024 * 1024, + maxFiles: 1, + maxFileSize: config["system_config"]["max_upload_file_size"], + testChunks: false, + query: { + csrftoken: csrftoken + } + }); + + that.uploader.assignBrowse($("#file-uploader-input", context)); + + var fileName = ""; + var file_input = false; + + that.uploader.on("fileAdded", function(file) { + fileName = file.fileName; + file_input = fileName; + + $("#file-uploader-input", context).hide(); + $("#file-uploader-label", context).html(file.fileName); + $("#file-uploader-label", context).show(); + $("#close_image", context).show(); + }); + + $("#close_image", context).on("click", function(){ + $("#file-uploader-label", context).hide(); + $("#close_image", context).hide(); + $("#file-uploader-input", context).show(); + fileName= ""; + that.uploader.files.length = 0; + }); + var last_time = 0; + var old_size = 0; + + that.uploader.on("uploadStart", function() { + last_time = new Date().getTime(); + old_size = 0; + var myThis = this; + if(!(myThis.progress() > 0)){ + var element = $("#upload_progress_bars").append( + "
\ +
\ + " + Locale.tr("Uploading...") + "\ +
\ +
\ +
"+ + ProgressBar.html(0, 1, fileName) + "\ +
\ +
\ + \ + \ + \ +
\ +
\ +
\ +
speed:
\ +
Completed:
\ +
\ +
"); + } + $(".close_upload_image").on("click", function(){ + myThis.cancel(); + show=0; + if(element) + element.remove(); + }); + $(".pause_upload_image").on("click", function(){ + myThis.pause(); + $(".pause_upload_image").hide(); + $(".play_upload_image").show(); + }); + $(".play_upload_image").on("click", function(){ + myThis.upload(); + $(".play_upload_image").hide(); + $(".pause_upload_image").show(); + }); + }); + + that.uploader.on("progress", function() { + var time = new Date().getTime(); + var size = this.getSize() * this.progress(); + if(time - last_time > 2000){ + size = size - old_size; + var speed = size / ((time - last_time)); + document.getElementById( "speed" ).textContent = "speed: " + Humanize.size(speed) +"s"; + last_time = time; + old_size = size; + } + document.getElementById( "percent_progress" ).textContent = "Completed: " + (this.progress().toFixed(3)*100).toFixed(1) +"%"; + $("div.progressbar", $("div[id=\"" + fileName + "progressBar\"]")).html( + ProgressBar.html(this.progress(), 1, fileName) ); + }); + } + + return false; + } + + function _submitWizard(context) { + var that = this; + var upload = false; + + var ds_id = $("#"+prepend+"_datastore .resource_list_select", context).val(); + if (!ds_id) { + Sunstone.hideFormPanelLoading(that.tabId); + Notifier.notifyError(Locale.tr("Please select a datastore for this image")); + return false; + } + + var img_json = {}; + + var name = WizardFields.retrieveInput($("#"+prepend+"_name", context)); + img_json["NAME"] = name; + + var desc = WizardFields.retrieveInput($("#"+prepend+"_desc", context)); + if (desc != undefined && desc.length) { + img_json["DESCRIPTION"] = desc; + } + + var type = WizardFields.retrieveInput($("#"+prepend+"_type", context)); + img_json["TYPE"] = type; + + img_json["PERSISTENT"] = $("#"+prepend+"_persistent", context).val(); + if ( img_json["PERSISTENT"] == "" ){ + delete img_json["PERSISTENT"]; + } + + var dev_prefix = WizardFields.retrieveInput($("#"+prepend+"_dev_prefix", context)); + if (dev_prefix != undefined && dev_prefix.length) { + if (dev_prefix == "custom") { + dev_prefix = WizardFields.retrieveInput($("#custom_img_dev_prefix", context)); + } + img_json["DEV_PREFIX"] = dev_prefix; + } + + var driver = WizardFields.retrieveInput($("#"+prepend+"_driver", context)); + if (driver != undefined && driver.length) { + if (driver == "custom") { + driver = WizardFields.retrieveInput($("#custom_img_driver", context)); + } + img_json["FORMAT"] = driver; + } + + var target = WizardFields.retrieveInput($("#"+prepend+"_target", context)); + if (target) + img_json["TARGET"] = target; + + var vcenter_adapter_type = WizardFields.retrieveInput($("#vcenter_adapter_type", context)); + if (vcenter_adapter_type) { + if (vcenter_adapter_type == "custom") { + vcenter_adapter_type = WizardFields.retrieveInput($("#custom_vcenter_adapter_type", context)); + } + img_json["VCENTER_ADAPTER_TYPE"] = vcenter_adapter_type; + } + + switch ($("#src_path_select input:checked", context).val()){ + case "path": + path = WizardFields.retrieveInput($("#"+prepend+"_path", context)); + if (path) img_json["PATH"] = path; + break; + case "datablock": + size = WizardFields.retrieveInput($("#"+prepend+"_size", context)); + + if(size && $(".mb_input_unit", context).val() == "GB"){ + size = size * 1024; + size = size.toString(); + } + if (size) img_json["SIZE"] = size; + + var vcenter_disk_type = WizardFields.retrieveInput($("#vcenter_disk_type", context)); + if (vcenter_disk_type) { + if (vcenter_disk_type == "custom"){ + vcenter_disk_type = WizardFields.retrieveInput($("#custom_disk_type", context)); + } + img_json["VCENTER_DISK_TYPE"] = vcenter_disk_type; + } + + break; + case "upload": + upload = true; + break; + } + + $.extend(img_json, CustomTagsTable.retrieve(context)); + + var img_obj = { + "image" : img_json, + "ds_id" : ds_id + }; + + //this is an image upload we trigger FileUploader + //to start the upload + if (upload) { + if (that.uploader.files.length == 0) { + Sunstone.hideFormPanelLoading(that.tabId); + Notifier.notifyError(Locale.tr("Please select a file to upload")); + return false; + } + + Sunstone.resetFormPanel(that.tabId, that.formPanelId); + Sunstone.hideFormPanel(that.tabId); + + that.uploader.on("fileSuccess", function(file) { + $("div[id=\"" + file.fileName + "-info\"]").text(Locale.tr("Registering in OpenNebula")); + $.ajax({ + url: "upload", + type: "POST", + data: { + csrftoken: csrftoken, + img : JSON.stringify(img_obj), + file: file.fileName, + tempfile: file.uniqueIdentifier + }, + success: function() { + Notifier.notifyMessage("Image uploaded correctly"); + $("div[id=\"" + file.fileName + "progressBar\"]").remove(); + Sunstone.runAction(that.resource+".refresh"); + }, + error: function(response) { + Notifier.onError({}, OpenNebulaError(response)); + $("div[id=\"" + file.fileName + "progressBar\"]").remove(); + } + }); + }); + + that.uploader.upload(); + } else { + Sunstone.runAction(that.resource+".create", img_obj); + } + + return false; + } + + function _submitAdvanced(context) { + var template = $("#template", context).val(); + var ds_id = $("#img_datastore_raw .resource_list_select", context).val(); + + if (!ds_id) { + Notifier.notifyError(Locale.tr("Please select a datastore for this image")); + return false; + } + + var img_obj = { + "image" : { + "image_raw" : template + }, + "ds_id" : ds_id + }; + + Sunstone.runAction(this.resource+".create", img_obj); + + return false; + } +}); diff --git a/src/sunstone/public/app/tabs/files-tab/form-panels/create.js b/src/sunstone/public/app/tabs/files-tab/form-panels/create.js index 6c91c25f8d..6670cf6798 100644 --- a/src/sunstone/public/app/tabs/files-tab/form-panels/create.js +++ b/src/sunstone/public/app/tabs/files-tab/form-panels/create.js @@ -19,15 +19,15 @@ define(function(require) { DEPENDENCIES */ - var BaseFormPanel = require('tabs/images-tab/form-panels/create-common'); + var BaseFormPanel = require("tabs/files-tab/form-panels/create-common"); /* CONSTANTS */ var RESOURCE = "File"; - var FORM_PANEL_ID = require('./create/formPanelId'); - var TAB_ID = require('../tabId'); + var FORM_PANEL_ID = require("./create/formPanelId"); + var TAB_ID = require("../tabId"); /* CONSTRUCTOR diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/advanced.hbs b/src/sunstone/public/app/tabs/files-tab/form-panels/create/advanced.hbs similarity index 91% rename from src/sunstone/public/app/tabs/images-tab/form-panels/create/advanced.hbs rename to src/sunstone/public/app/tabs/files-tab/form-panels/create/advanced.hbs index 708d741d69..c579a4e2c5 100644 --- a/src/sunstone/public/app/tabs/images-tab/form-panels/create/advanced.hbs +++ b/src/sunstone/public/app/tabs/files-tab/form-panels/create/advanced.hbs @@ -17,8 +17,8 @@
- -
+ +
diff --git a/src/sunstone/public/app/tabs/files-tab/form-panels/create/formPanelId.js b/src/sunstone/public/app/tabs/files-tab/form-panels/create/formPanelId.js index d20cb1385b..af4cc91d4d 100644 --- a/src/sunstone/public/app/tabs/files-tab/form-panels/create/formPanelId.js +++ b/src/sunstone/public/app/tabs/files-tab/form-panels/create/formPanelId.js @@ -15,5 +15,5 @@ /* -------------------------------------------------------------------------- */ define(function(require){ - return 'createFileForm'; + return "createFileForm"; }); diff --git a/src/sunstone/public/app/tabs/files-tab/form-panels/create/wizard.hbs b/src/sunstone/public/app/tabs/files-tab/form-panels/create/wizard.hbs new file mode 100644 index 0000000000..eebc55dca6 --- /dev/null +++ b/src/sunstone/public/app/tabs/files-tab/form-panels/create/wizard.hbs @@ -0,0 +1,111 @@ +{{! -------------------------------------------------------------------------- }} +{{! Copyright 2002-2021, OpenNebula Project, OpenNebula Systems }} +{{! }} +{{! 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. }} +{{! -------------------------------------------------------------------------- }} + + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ +
+
+
+
+
+ {{tr "Image location"}} +
+
+ + + + +
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+ +
+
+
+
+ diff --git a/src/sunstone/public/app/tabs/files-tab/tabId.js b/src/sunstone/public/app/tabs/files-tab/tabId.js index 912b1df737..48723d5bd2 100644 --- a/src/sunstone/public/app/tabs/files-tab/tabId.js +++ b/src/sunstone/public/app/tabs/files-tab/tabId.js @@ -15,5 +15,5 @@ /* -------------------------------------------------------------------------- */ define(function(require){ - return 'files-tab'; -}) + return "files-tab"; +}); diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create-common.js b/src/sunstone/public/app/tabs/images-tab/form-panels/create-common.js index b54927bb44..e0d19d89f9 100644 --- a/src/sunstone/public/app/tabs/images-tab/form-panels/create-common.js +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create-common.js @@ -20,40 +20,43 @@ define(function(require) { */ var BaseFormPanel = require("utils/form-panels/form-panel"); - var Resumable = require("resumable"); var Sunstone = require("sunstone"); var OpenNebulaError = require("opennebula/error"); var Notifier = require("utils/notifier"); var Locale = require("utils/locale"); - var Tips = require("utils/tips"); - var OpenNebulaDatastore = require("opennebula/datastore"); - var ResourceSelect = require("utils/resource-select"); - var CustomTagsTable = require("utils/custom-tags-table"); - var BrowserInfo = require("utils/browser-info"); - var Config = require("sunstone-config"); var WizardFields = require("utils/wizard-fields"); - var ProgressBar = require("utils/progress-bar"); - var Humanize = require("utils/humanize"); - - var TemplateWizardHTML = require("hbs!./create/wizard"); - var TemplateAdvancedHTML = require("hbs!./create/advanced"); + var TemplateTabsHTML = require("hbs!./create/tabs"); + var CustomTagsTable = require("utils/custom-tags-table"); /* CONSTANTS */ - + var WIZARD_TABS = [ + require("./create/wizard-tabs/image"), + require("./create/wizard-tabs/docker"), + ]; + var IMAGES_TAB_ID = require("tabs/images-tab/tabId"); + var typeSender = "wizard"; /* CONSTRUCTOR */ - function FormPanel() { - var title; + var title = Locale.tr("Create Image"); + var that = this; + var tabId = IMAGES_TAB_ID; + var formPanelId = (that && that.formPanelId)||""; + that.wizardTabs = []; + var wizardTabCreate; - if (this.resource == "Image"){ - title = Locale.tr("Create Image"); - } else { - title = Locale.tr("Create File"); - } + $.each(WIZARD_TABS, function(index, wizardTab) { + try { + wizardTabCreate = new wizardTab({formPanelId: formPanelId, tabId: tabId}); + wizardTabCreate.contentHTML = wizardTabCreate.html(); + that.wizardTabs.push(wizardTabCreate); + } catch (err) { + console.log(err); + } + }); this.actions = { "create": { @@ -63,17 +66,98 @@ define(function(require) { } }; - BaseFormPanel.call(this); + // BaseFormPanel.call(this); + } + + function _reInit(context){ + var that = this; + //this clear events into forms "" + $("#"+that.formPanelId+"Wizard, #"+that.formPanelId+"Advanced") + .off("forminvalid.zf.abide") + .off("formvalid.zf.abide") + .off("submit") + .on("submit", function(ev){ + that.submitWizard(context); + ev.preventDefault(); + return false; + }); + } + + function errorSubmit(element, tabId, context){ + if(element && tabId){ + $(element).off("forminvalid.zf.abide").on("forminvalid.zf.abide", function(ev, frm) { + Notifier.notifyError(Locale.tr("One or more required fields are missing or malformed."),ev.target,context); + Sunstone.hideFormPanelLoading(tabId); + }); + } + } + + function successSubmit(element, callback, that){ + if(element && callback && typeof callback === "function"){ + $(element).off("formvalid.zf.abide").on("formvalid.zf.abide", function(ev, frm){ + callback(that, frm); + }); + } + } + + function resetOtherForms (form, formPanelId) { + if(form && formPanelId){ + var forms = ["Docker","Advanced","Wizard"]; + forms.forEach(element => { + if(form !== element){ + try { + $("#"+formPanelId+element).foundation("resetForm"); + } catch (error) {} + } + }); + } + } + + function _submit(context){ + var that = this; + switch (typeSender) { + case "docker": + var element = "#"+that.formPanelId+"Docker"; + + //reset other forms + resetOtherForms("Docker",that.formPanelId); + + errorSubmit(element, that.tabId, context); + successSubmit(element, _submitDocker, that); + $(element).foundation("validateForm"); + break; + + case "advanced": + var element = "#"+that.formPanelId+"Advanced"; + + //reset other forms + resetOtherForms("Advanced", that.formPanelId); + + errorSubmit(element, that.tabId, context); + successSubmit(element, _submitAdvanced, that); + $(element).foundation("validateForm"); + break; + + default: + var element = "#"+that.formPanelId+"Wizard"; + + //reset other forms + resetOtherForms("Wizard", that.formPanelId); + + errorSubmit(element, that.tabId, context); + successSubmit(element, _submitWizard, that); + $(element).foundation("validateForm"); + break; + } } FormPanel.prototype = Object.create(BaseFormPanel.prototype); FormPanel.prototype.constructor = FormPanel; FormPanel.prototype.htmlWizard = _htmlWizard; - FormPanel.prototype.htmlAdvanced = _htmlAdvanced; - FormPanel.prototype.submitWizard = _submitWizard; - FormPanel.prototype.submitAdvanced = _submitAdvanced; + FormPanel.prototype.submitWizard = _submit; FormPanel.prototype.onShow = _onShow; FormPanel.prototype.setup = _setup; + FormPanel.prototype.reInit = _reInit; return FormPanel; @@ -82,306 +166,49 @@ define(function(require) { FUNCTION DEFINITIONS */ + function changeTypeSender(attr){ + if(attr){ + typeSender = attr; + } + } + function _htmlWizard() { - return TemplateWizardHTML({ + return TemplateTabsHTML({ "formPanelId": this.formPanelId, - "customTagsHTML": CustomTagsTable.html(), - "images": (this.resource == "Image") + "wizardTabs": this.wizardTabs }); } - function _htmlAdvanced() { - return TemplateAdvancedHTML({formPanelId: this.formPanelId}); - } - function _onShow(context) { - $("#img_driver").val(""); - $("#img_name", context).focus(); + var that = this; + //click on image tag + $("a[href=\"#"+ that.wizardTabs[0].wizardTabId +"\"]", context).trigger("click"); + //click on wizard sub tab + $("a[href=\"#createImageFormWizard\"]", context).trigger("click"); - var ds_id = $("#img_datastore .resource_list_select", context).val(); - var ds_id_raw = $("#img_datastore_raw .resource_list_select", context).val(); - - var filterValue; - - if (this.resource == "Image"){ - filterValue = "" + OpenNebulaDatastore.TYPES.IMAGE_DS; - } else { - filterValue = "" + OpenNebulaDatastore.TYPES.FILE_DS; - } - - ResourceSelect.insert({ - context: $("#img_datastore", context), - resourceName: "Datastore", - initValue: ds_id, - filterKey: "TYPE", - filterValue: filterValue, - triggerChange: true - }); - - ResourceSelect.insert({ - context: $("#img_datastore_raw", context), - resourceName: "Datastore", - initValue: ds_id_raw, - filterKey: "TYPE", - filterValue: filterValue, - triggerChange: true - }); - - return false; + $.each(that.wizardTabs, function(index, wizardTab) { + wizardTab.onShow($("#" + wizardTab.wizardTabId, context), that); + }); + $(".changeTypeSender").each(function(){ + var attr = $(this).attr("data-typesender"); + if (typeof attr !== typeof undefined && attr !== false){ + $(this).on("click", function(){ + changeTypeSender(attr); + }); + } + }); } function _setup(context) { - var that = this; - Tips.setup(context); - - $("select#img_type", context).change(function() { - var value = $(this).val(); - switch (value){ - case "DATABLOCK": - case "OS": - $("#datablock_img", context).removeAttr("disabled"); - break; - default: - $("#datablock_img", context).attr("disabled", "disabled"); - $("#path_image", context).click(); - } + $.each(this.wizardTabs, function(index, wizardTab) { + wizardTab.setup($("#" + wizardTab.wizardTabId, context)); }); - if(config["federation_mode"] == "SLAVE"){ - $("#upload_image").attr("disabled", "disabled"); - } - - $("#img_datastore", context).off("change", ".resource_list_select"); - $("#img_datastore", context).on("change", ".resource_list_select", function() { - var ds_id = $(this).val(); - OpenNebulaDatastore.show({ - data : { - id: ds_id - }, - timeout: true, - success: function(request, ds){ - var mad = ds["DATASTORE"]["DS_MAD"]; - var tm_mad = ds["DATASTORE"]["TM_MAD"]; - - var pers_forced = false; - - // Set the persistency - if (Config.onedConf.DS_MAD_CONF !== undefined) { - $.each(Config.onedConf.DS_MAD_CONF, function(i,e){ - if (e["NAME"] == mad && !$.isEmptyObject(e["PERSISTENT_ONLY"])) { - if (e["PERSISTENT_ONLY"] != undefined && - e["PERSISTENT_ONLY"].toLowerCase() == "yes") { - $("#img_persistent", context).prop("disabled", true); - $("#img_persistent", context).val("YES"); - pers_forced = true; - return false; - } - } - } - ); - } - - if (!pers_forced) { - $("#img_persistent", context).prop("disabled", false); - } - - // Display adequate values in the dialog. - switch (mad) { - case "vcenter": - $(".only_vcenter").show(); - $(".not_vcenter").hide(); - break; - default: - $(".only_vcenter").hide(); - $(".not_vcenter").show(); - } - - // Fill in the default driver - if (tm_mad == "qcow2"){ - $("select#img_driver",context).val("qcow2"); - } else { - //$("select#img_driver",context).val("raw"); - } - }, - error: function(request, error_json, container){ - Notifier.onError(request, error_json, container); - } - }); - }); - - // Custom Adapter Type - var custom_attrs = [ - "vcenter_adapter_type", - "vcenter_disk_type", - "img_dev_prefix", - "img_driver" - ]; - - $(custom_attrs).each(function(_, field) { - $("input[name=\"custom_"+field+"\"]",context).parent().hide(); - - $("select#"+field, context).on("change", function() { - var field = $(this).attr("name"); - - if ($(this).val() == "custom"){ - $("input[name=\"custom_"+field+"\"]",context).parent().show(); - $("input[name=\"custom_"+field+"\"]",context).attr("required", ""); - } else { - $("input[name=\"custom_"+field+"\"]",context).parent().hide(); - $("input[name=\"custom_"+field+"\"]",context).removeAttr("required"); - } - }); - }); - - $("#img_path,#img_size,#file-uploader", context).closest(".row").hide(); - $("input[name='src_path']", context).change(function() { - var value = $(this).val(); - switch (value){ - case "path": - $("#img_size,#file-uploader", context).closest(".row").hide(); - $("#img_path", context).closest(".row").show(); - $("#img_path", context).attr("required", ""); - $("#img_size", context).removeAttr("required"); - $(".datablock-input, .upload-input").addClass("hide"); - $(".path-input").removeClass("hide"); - $("#img_driver").val(""); - break; - case "datablock": - $("#img_path,#file-uploader", context).closest(".row").hide(); - $("#img_size", context).closest(".row").show(); - $("#img_path", context).removeAttr("required"); - $("#img_size", context).attr("required", ""); - $(".path-input, .upload-input").addClass("hide"); - $(".datablock-input").removeClass("hide"); - break; - case "upload": - $("#img_path,#img_size", context).closest(".row").hide(); - $("#file-uploader", context).closest(".row").show(); - $("#img_path", context).removeAttr("required"); - $("#img_size", context).removeAttr("required"); - $(".path-input, .datablock-input").addClass("hide"); - $(".upload-input").removeClass("hide"); - $("#img_driver").val(""); - break; - } - }); - - $("#img_type", context).change(function() { - var value = $(this).val(); - if(value == "CDROM") - $("#img_persistent", context).closest(".row").hide(); - else - $("#img_persistent", context).closest(".row").show(); - }); - - $("#path_image", context).click(); - - CustomTagsTable.setup(context); - - if (BrowserInfo.getInternetExplorerVersion() > -1) { - $("#upload_image").attr("disabled", "disabled"); - } else { - that.uploader = new Resumable({ - target: "upload_chunk", - chunkSize: 10 * 1024 * 1024, - maxFiles: 1, - maxFileSize: config["system_config"]["max_upload_file_size"], - testChunks: false, - query: { - csrftoken: csrftoken - } - }); - - that.uploader.assignBrowse($("#file-uploader-input", context)); - - var fileName = ""; - var file_input = false; - - that.uploader.on("fileAdded", function(file) { - fileName = file.fileName; - file_input = fileName; - - $("#file-uploader-input", context).hide(); - $("#file-uploader-label", context).html(file.fileName); - $("#file-uploader-label", context).show(); - $("#close_image", context).show(); - }); - - $("#close_image", context).on("click", function(){ - $("#file-uploader-label", context).hide(); - $("#close_image", context).hide(); - $("#file-uploader-input", context).show(); - fileName= ""; - that.uploader.files.length = 0; - }); - var last_time = 0; - var old_size = 0; - - that.uploader.on("uploadStart", function() { - last_time = new Date().getTime(); - old_size = 0; - var myThis = this; - if(!(myThis.progress() > 0)){ - var element = $("#upload_progress_bars").append( - "
\ -
\ - " + Locale.tr("Uploading...") + "\ -
\ -
\ -
"+ - ProgressBar.html(0, 1, fileName) + "\ -
\ -
\ - \ - \ - \ -
\ -
\ -
\ -
speed:
\ -
Completed:
\ -
\ -
"); - } - $(".close_upload_image").on("click", function(){ - myThis.cancel(); - show=0; - if(element) - element.remove(); - }); - $(".pause_upload_image").on("click", function(){ - myThis.pause(); - $(".pause_upload_image").hide(); - $(".play_upload_image").show(); - }); - $(".play_upload_image").on("click", function(){ - myThis.upload(); - $(".play_upload_image").hide(); - $(".pause_upload_image").show(); - }); - }); - - that.uploader.on("progress", function() { - var time = new Date().getTime(); - var size = this.getSize() * this.progress(); - if(time - last_time > 2000){ - size = size - old_size; - var speed = size / ((time - last_time)); - document.getElementById( "speed" ).textContent = "speed: " + Humanize.size(speed) +"s"; - last_time = time; - old_size = size; - } - document.getElementById( "percent_progress" ).textContent = "Completed: " + (this.progress().toFixed(3)*100).toFixed(1) +"%"; - $("div.progressbar", $("div[id=\"" + fileName + "progressBar\"]")).html( - ProgressBar.html(this.progress(), 1, fileName) ); - }); - } - - return false; + Foundation.reflow(context, "tabs"); + Foundation.reflow(context, "tooltip"); } - function _submitWizard(context) { - var that = this; + function _submitWizard(that, context) { var upload = false; var ds_id = $("#img_datastore .resource_list_select", context).val(); @@ -515,9 +342,54 @@ define(function(require) { return false; } - function _submitAdvanced(context) { + function _submitDocker(that, context){ + var name = $("#docker_name", context).val(); + var ds_id = $("#docker_datastore .resource_list_select", context).val(); + var cntext = $("#docker_context", context).val(); + var size = parseInt($("#docker_size", context).val(), 10) || 0; + var template = ""; + var sizeUnit = parseInt($("#docker_size_units", context).val(),10) || 1; + + size = size * sizeUnit; + + // that.wizardTabs[1] is tab docker see line 34 of this file + if (that.wizardTabs && that.wizardTabs[1] && that.wizardTabs[1].getValueEditor && typeof that.wizardTabs[1].getValueEditor === "function") { + template = that.wizardTabs[1].getValueEditor().trim(); + } + + if (!ds_id) { + Sunstone.hideFormPanelLoading(that.tabId); + Notifier.notifyError(Locale.tr("Please select a datastore")); + return false; + } + + if(!template){ + Sunstone.hideFormPanelLoading(that.tabId); + Notifier.notifyError(Locale.tr("Please insert a dockerfile template")); + return false; + }else{ + template = btoa(template); + } + + if (!size) { + Sunstone.hideFormPanelLoading(that.tabId); + Notifier.notifyError(Locale.tr("Please select a size")); + return false; + } + var img_obj = { + "image" : { + "NAME" : name, + "PATH" : "dockerfile://?fileb64="+template+"&context="+cntext+"&size="+size.toString() + }, + "ds_id" : ds_id + }; + Sunstone.runAction(that.resource+".create", img_obj); + return false; + } + + function _submitAdvanced(that, context) { var template = $("#template", context).val(); - var ds_id = $("#img_datastore_raw .resource_list_select", context).val(); + var ds_id = $("#img_datastore_raw_advanced .resource_list_select", context).val(); if (!ds_id) { Notifier.notifyError(Locale.tr("Please select a datastore for this image")); @@ -531,7 +403,7 @@ define(function(require) { "ds_id" : ds_id }; - Sunstone.runAction(this.resource+".create", img_obj); + Sunstone.runAction(that.resource+".create", img_obj); return false; } diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create.js b/src/sunstone/public/app/tabs/images-tab/form-panels/create.js index 43502f09cd..1e8b7b8fd4 100644 --- a/src/sunstone/public/app/tabs/images-tab/form-panels/create.js +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create.js @@ -19,15 +19,15 @@ define(function(require) { DEPENDENCIES */ - var BaseFormPanel = require('tabs/images-tab/form-panels/create-common'); + var BaseFormPanel = require("tabs/images-tab/form-panels/create-common"); /* CONSTANTS */ var RESOURCE = "Image"; - var FORM_PANEL_ID = require('./create/formPanelId'); - var TAB_ID = require('../tabId'); + var FORM_PANEL_ID = require("./create/formPanelId"); + var TAB_ID = require("../tabId"); /* CONSTRUCTOR diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/formPanelId.js b/src/sunstone/public/app/tabs/images-tab/form-panels/create/formPanelId.js index 64d3e9ea54..d4be8c0acb 100644 --- a/src/sunstone/public/app/tabs/images-tab/form-panels/create/formPanelId.js +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/formPanelId.js @@ -15,5 +15,5 @@ /* -------------------------------------------------------------------------- */ define(function(require){ - return 'createImageForm'; -}) + return "createImageForm"; +}); diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/tabs.hbs b/src/sunstone/public/app/tabs/images-tab/form-panels/create/tabs.hbs new file mode 100644 index 0000000000..7b00ab1754 --- /dev/null +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/tabs.hbs @@ -0,0 +1,39 @@ +{{! -------------------------------------------------------------------------- }} +{{! Copyright 2002-2021, OpenNebula Project, OpenNebula Systems }} +{{! }} +{{! 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. }} +{{! -------------------------------------------------------------------------- }} + +
+
+ {{#each wizardTabs}} +
+ + +
{{title}} +
+
+ {{/each}} +
+
+ {{#each wizardTabs}} +
+ {{{contentHTML}}} +
+ {{/each}} +
+
diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker.js b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker.js new file mode 100644 index 0000000000..0fef542553 --- /dev/null +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker.js @@ -0,0 +1,112 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +define(function(require) { + /* + DEPENDENCIES + */ + + var Config = require("sunstone-config"); + var Locale = require("utils/locale"); + var Tips = require("utils/tips"); + var WizardFields = require("utils/wizard-fields"); + var FilesTable = require("tabs/files-tab/datatable"); + var UniqueId = require("utils/unique-id"); + var OpenNebulaAction = require("opennebula/action"); + var ResourceSelect = require("utils/resource-select"); + var OpenNebulaDatastore = require("opennebula/datastore"); + var aceBuilds = require("ace-builds"); + + /* + TEMPLATES + */ + + var TemplateHTML = require("hbs!./docker/html"); + + /* + CONSTANTS + */ + + var WIZARD_TAB_ID = require("./docker/wizardTabId"); + + /* + CONSTRUCTOR + */ + var prepend = "docker"; + + function WizardTab(opts) { + this.editor; + this.getValueEditor = function(){ + var rtn = ""; + try { + rtn = this.editor.getValue(); + } catch (error) {} + return rtn; + }; + if (!Config.isTemplateCreationTabEnabled(opts.tabId, "docker")) { + throw "Wizard Tab not enabled"; + } + this.wizardTabId = WIZARD_TAB_ID + UniqueId.id(); + this.icon = "fa-file-code"; + this.title = Locale.tr("Dockerfile"); + this.formPanelId = opts.formPanelId || ""; + this.typeSender = "docker"; + } + + WizardTab.prototype.constructor = WizardTab; + WizardTab.prototype.html = _html; + WizardTab.prototype.setup = _setup; + WizardTab.prototype.onShow = _onShow; + // WizardTab.prototype.retrieve = _retrieve; + // WizardTab.prototype.fill = _fill; + + return WizardTab; + + /* + FUNCTION DEFINITIONS + */ + + function _html() { + var that = this; + return TemplateHTML({ + "prepend": prepend, + "formPanelId": that.formPanelId, + }); + } + + function _onShow(context, panelForm) { + var ds_id = $("#"+prepend+"_datastore .resource_list_select", context).val(); + var filterValue = OpenNebulaDatastore.TYPES.IMAGE_DS; + ResourceSelect.insert({ + context: $("#"+prepend+"_datastore", context), + resourceName: "Datastore", + initValue: ds_id, + filterKey: "TYPE", + filterValue: filterValue.toString(), + triggerChange: true + }); + ace.config.set("basePath", "/bower_components/ace-builds"); + this.editor = ace.edit("docker_template"); + this.editor.setTheme("ace/theme/github"); + this.editor.session.setMode("ace/mode/dockerfile"); + } + + function _setup(context) { + var that = this; + Foundation.reflow(context, "tabs"); + } +}); + diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker/html.hbs b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker/html.hbs new file mode 100644 index 0000000000..cead3fa837 --- /dev/null +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker/html.hbs @@ -0,0 +1,37 @@ +
+
+
+ + +
+
+ +
+
+
+
+
+ + +
+
+ +
+ + +
+
+
+
+
+

{{tr "Write the Dockerfile template here"}}

+
+
+
+
\ No newline at end of file diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker/wizardTabId.js b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker/wizardTabId.js new file mode 100644 index 0000000000..3b69146ffc --- /dev/null +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/docker/wizardTabId.js @@ -0,0 +1,21 @@ + +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +define(function(require){ + return "dockerImageCreateTab"; +}); + diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image.js b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image.js new file mode 100644 index 0000000000..c57047fb1c --- /dev/null +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image.js @@ -0,0 +1,385 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +define(function(require) { + /* + DEPENDENCIES + */ + + var Config = require("sunstone-config"); + var Locale = require("utils/locale"); + var Tips = require("utils/tips"); + var WizardFields = require("utils/wizard-fields"); + var FilesTable = require("tabs/files-tab/datatable"); + var UniqueId = require("utils/unique-id"); + var OpenNebulaAction = require("opennebula/action"); + + var Sunstone = require("sunstone"); + var CustomTagsTable = require("utils/custom-tags-table"); + var ResourceSelect = require("utils/resource-select"); + var BrowserInfo = require("utils/browser-info"); + var Resumable = require("resumable"); + var OpenNebulaDatastore = require("opennebula/datastore"); + var ProgressBar = require("utils/progress-bar"); + var Humanize = require("utils/humanize"); + + /* + TEMPLATES + */ + var WrapperTaps = require("hbs!../wrapper"); + var TemplateHTML = require("hbs!./image/html"); + var TemplateAdvancedHTML = require("hbs!./image/advanced"); + + /* + CONSTANTS + */ + + var WIZARD_TAB_ID = require("./image/wizardTabId"); + var prepend = "img"; + /* + CONSTRUCTOR + */ + + function WizardTab(opts) { + if (!Config.isTemplateCreationTabEnabled(opts.tabId, "image")) { + throw "Wizard Tab not enabled"; + } + this.wizardTabId = WIZARD_TAB_ID + UniqueId.id(); + this.icon = "fa-edit"; + this.title = Locale.tr("Image"); + this.formPanelId = opts.formPanelId || ""; + this.typeSender = "wizard"; + } + + WizardTab.prototype.constructor = WizardTab; + WizardTab.prototype.html = _html; + WizardTab.prototype.setup = _setup; + WizardTab.prototype.onShow = _onShow; + WizardTab.prototype.retrieve = _retrieve; + WizardTab.prototype.fill = _fill; + + return WizardTab; + + /* + FUNCTION DEFINITIONS + */ + + function _html() { + var that = this; + + //this alls forms of Image template + return WrapperTaps({ + "formPanelId": this.formPanelId, + "form": TemplateHTML({ + "prepend": prepend, + "formPanelId": this.formPanelId, + "customTagsHTML": CustomTagsTable.html(), + }), + "advanced": TemplateAdvancedHTML({ + "prepend": prepend, + "formPanelId": this.formPanelId + }) + }); + } + + function _onShow(context, panelForm) { + $("#"+this.formPanelId+"InternalTabs").css({"display":"flex"}); + $("#"+prepend+"_driver").val(""); + $("#"+prepend+"_name", context).focus(); + var ds_id = $("#"+prepend+"_datastore .resource_list_select", context).val(); + var ds_id_raw = $("#"+prepend+"_datastore_raw .resource_list_select", context).val(); + var filterValue = OpenNebulaDatastore.TYPES.IMAGE_DS; + ResourceSelect.insert({ + context: $("#"+prepend+"_datastore", context), + resourceName: "Datastore", + initValue: ds_id, + filterKey: "TYPE", + filterValue: filterValue.toString(), + triggerChange: true + }); + ResourceSelect.insert({ + context: $("#"+prepend+"_datastore_raw", context), + resourceName: "Datastore", + initValue: ds_id_raw, + filterKey: "TYPE", + filterValue: filterValue.toString(), + triggerChange: true + }); + ResourceSelect.insert({ + context: $("#"+prepend+"_datastore_raw_advanced", context), + resourceName: "Datastore", + initValue: ds_id_raw, + filterKey: "TYPE", + filterValue: filterValue.toString(), + triggerChange: true + }); + return false; + } + + function _setup(context) { + var that = this; + Tips.setup(context); + $("select#"+prepend+"_type", context).change(function() { + var value = $(this).val(); + switch (value){ + case "DATABLOCK": + case "OS": + $("#datablock_img", context).removeAttr("disabled"); + break; + default: + $("#datablock_img", context).attr("disabled", "disabled"); + $("#path_image", context).click(); + } + }); + if(config["federation_mode"] == "SLAVE"){ + $("#upload_image").attr("disabled", "disabled"); + } + + $("#"+prepend+"_datastore", context).off("change", ".resource_list_select"); + $("#"+prepend+"_datastore", context).on("change", ".resource_list_select", function() { + var ds_id = $(this).val(); + OpenNebulaDatastore.show({ + data : { + id: ds_id + }, + timeout: true, + success: function(request, ds){ + var mad = ds["DATASTORE"]["DS_MAD"]; + var tm_mad = ds["DATASTORE"]["TM_MAD"]; + + var pers_forced = false; + + // Set the persistency + if (Config.onedConf.DS_MAD_CONF !== undefined) { + $.each(Config.onedConf.DS_MAD_CONF, function(i,e){ + if (e["NAME"] == mad && !$.isEmptyObject(e["PERSISTENT_ONLY"])) { + if (e["PERSISTENT_ONLY"] != undefined && + e["PERSISTENT_ONLY"].toLowerCase() == "yes") { + $("#"+prepend+"_persistent", context).prop("disabled", true); + $("#"+prepend+"_persistent", context).val("YES"); + pers_forced = true; + return false; + } + } + } + ); + } + + if (!pers_forced) { + $("#"+prepend+"_persistent", context).prop("disabled", false); + } + + // Display adequate values in the dialog. + switch (mad) { + case "vcenter": + $(".only_vcenter").show(); + $(".not_vcenter").hide(); + break; + default: + $(".only_vcenter").hide(); + $(".not_vcenter").show(); + } + + // Fill in the default driver + if (tm_mad == "qcow2"){ + $("select#"+prepend+"_driver",context).val("qcow2"); + } + }, + error: function(request, error_json, container){ + Notifier.onError(request, error_json, container); + } + }); + }); + + // Custom Adapter Type + var custom_attrs = [ + "vcenter_adapter_type", + "vcenter_disk_type", + "img_dev_prefix", + "img_driver" + ]; + + $(custom_attrs).each(function(_, field) { + $("input[name=\"custom_"+field+"\"]",context).parent().hide(); + + $("select#"+field, context).on("change", function() { + var field = $(this).attr("name"); + + if ($(this).val() == "custom"){ + $("input[name=\"custom_"+field+"\"]",context).parent().show(); + $("input[name=\"custom_"+field+"\"]",context).attr("required", ""); + } else { + $("input[name=\"custom_"+field+"\"]",context).parent().hide(); + $("input[name=\"custom_"+field+"\"]",context).removeAttr("required"); + } + }); + }); + + $("#"+prepend+"_path,#"+prepend+"_size,#file-uploader", context).closest(".row").hide(); + $("input[name='src_path']", context).change(function() { + var value = $(this).val(); + switch (value){ + case "path": + $("#"+prepend+"_size,#file-uploader", context).closest(".row").hide(); + $("#"+prepend+"_path", context).closest(".row").show(); + $("#"+prepend+"_path", context).attr("required", ""); + $("#"+prepend+"_size", context).removeAttr("required"); + $(".datablock-input, .upload-input").addClass("hide"); + $(".path-input").removeClass("hide"); + $("#"+prepend+"_driver").val(""); + break; + case "datablock": + $("#"+prepend+"_path,#file-uploader", context).closest(".row").hide(); + $("#"+prepend+"_size", context).closest(".row").show(); + $("#"+prepend+"_path", context).removeAttr("required"); + $("#"+prepend+"_size", context).attr("required", ""); + $(".path-input, .upload-input").addClass("hide"); + $(".datablock-input").removeClass("hide"); + break; + case "upload": + $("#"+prepend+"_path,#"+prepend+"_size", context).closest(".row").hide(); + $("#file-uploader", context).closest(".row").show(); + $("#"+prepend+"_path", context).removeAttr("required"); + $("#"+prepend+"_size", context).removeAttr("required"); + $(".path-input, .datablock-input").addClass("hide"); + $(".upload-input").removeClass("hide"); + $("#"+prepend+"_driver").val(""); + break; + } + }); + + $("#"+prepend+"_type", context).change(function() { + var value = $(this).val(); + if(value == "CDROM") + $("#"+prepend+"_persistent", context).closest(".row").hide(); + else + $("#"+prepend+"_persistent", context).closest(".row").show(); + }); + + $("#path_image", context).click(); + + CustomTagsTable.setup(context); + + if (BrowserInfo.getInternetExplorerVersion() > -1) { + $("#upload_image").attr("disabled", "disabled"); + } else { + that.uploader = new Resumable({ + target: "upload_chunk", + chunkSize: 10 * 1024 * 1024, + maxFiles: 1, + maxFileSize: config["system_config"]["max_upload_file_size"], + testChunks: false, + query: { + csrftoken: csrftoken + } + }); + + that.uploader.assignBrowse($("#file-uploader-input", context)); + + var fileName = ""; + var file_input = false; + + that.uploader.on("fileAdded", function(file) { + fileName = file.fileName; + file_input = fileName; + + $("#file-uploader-input", context).hide(); + $("#file-uploader-label", context).html(file.fileName); + $("#file-uploader-label", context).show(); + $("#close_image", context).show(); + }); + + $("#close_image", context).on("click", function(){ + $("#file-uploader-label", context).hide(); + $("#close_image", context).hide(); + $("#file-uploader-input", context).show(); + fileName= ""; + that.uploader.files.length = 0; + }); + var last_time = 0; + var old_size = 0; + + that.uploader.on("uploadStart", function() { + last_time = new Date().getTime(); + old_size = 0; + var myThis = this; + if(!(myThis.progress() > 0)){ + var element = $("#upload_progress_bars").append( + "
\ +
\ + " + Locale.tr("Uploading...") + "\ +
\ +
\ +
"+ + ProgressBar.html(0, 1, fileName) + "\ +
\ +
\ + \ + \ + \ +
\ +
\ +
\ +
speed:
\ +
Completed:
\ +
\ +
"); + } + $(".close_upload_image").on("click", function(){ + myThis.cancel(); + show=0; + if(element) + element.remove(); + }); + $(".pause_upload_image").on("click", function(){ + myThis.pause(); + $(".pause_upload_image").hide(); + $(".play_upload_image").show(); + }); + $(".play_upload_image").on("click", function(){ + myThis.upload(); + $(".play_upload_image").hide(); + $(".pause_upload_image").show(); + }); + }); + + that.uploader.on("progress", function() { + var time = new Date().getTime(); + var size = this.getSize() * this.progress(); + if(time - last_time > 2000){ + size = size - old_size; + var speed = size / ((time - last_time)); + document.getElementById( "speed" ).textContent = "speed: " + Humanize.size(speed) +"s"; + last_time = time; + old_size = size; + } + document.getElementById( "percent_progress" ).textContent = "Completed: " + (this.progress().toFixed(3)*100).toFixed(1) +"%"; + $("div.progressbar", $("div[id=\"" + fileName + "progressBar\"]")).html( + ProgressBar.html(this.progress(), 1, fileName) ); + }); + } + Foundation.reflow(context, "tabs"); + return false; + } + + function _retrieve(context) { + } + + function _fill(context, templateJSON) { + } + +}); + diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image/advanced.hbs b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image/advanced.hbs new file mode 100644 index 0000000000..87c6873c40 --- /dev/null +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image/advanced.hbs @@ -0,0 +1,34 @@ +{{! -------------------------------------------------------------------------- }} +{{! Copyright 2002-2021, OpenNebula Project, OpenNebula Systems }} +{{! }} +{{! 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. }} +{{! -------------------------------------------------------------------------- }} + +
+
+
+ +
+
+
+
+
+

{{tr "Write the Image template here"}}

+
+
+
+
+ +
+
+
diff --git a/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard.hbs b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image/html.hbs similarity index 81% rename from src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard.hbs rename to src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image/html.hbs index c422f04df7..25d5d82de2 100644 --- a/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard.hbs +++ b/src/sunstone/public/app/tabs/images-tab/form-panels/create/wizard-tabs/image/html.hbs @@ -1,5 +1,5 @@ {{! -------------------------------------------------------------------------- }} -{{! Copyright 2002-2021, OpenNebula Project, OpenNebula Systems }} +{{! Copyright 2002-2020, OpenNebula Project, OpenNebula Systems }} {{! }} {{! 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 }} @@ -14,46 +14,39 @@ {{! limitations under the License. }} {{! -------------------------------------------------------------------------- }} -
+
-
-
-
-
- {{#if images}} {{#isTabActionEnabled "images-tab" "Image.persistent"}}
@@ -64,7 +57,7 @@
- @@ -74,7 +67,6 @@
{{/isTabActionEnabled}} - {{/if}}
{{tr "Image location"}} @@ -84,19 +76,17 @@ - {{#if images}} - {{/if}}

-
@@ -106,14 +96,14 @@
-
+
-