1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-10 13:57:22 +03:00

F #5056: Add dockerfile support in Sunstone

Co-authored-by: Jorge Lobo <jlobo@opennebula.systems>
This commit is contained in:
Jorge Miguel Lobo Escalona 2021-02-09 13:51:41 +01:00 committed by GitHub
parent 08f202395d
commit 72fb38865c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 1601 additions and 387 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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"],

View File

@ -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

View File

@ -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(
"<div id=\"" + fileName + "progressBar\" class=\"row\" style=\"margin-bottom:10px\">\
<div id=\"" + fileName + "-info\" class=\"medium-2 columns\">\
" + Locale.tr("Uploading...") + "\
</div>\
<div class=\"medium-10 columns\">\
<div class=\"progressbar\">"+
ProgressBar.html(0, 1, fileName) + "\
</div>\
<div>\
<button id=\"close_upload_image\" class=\"fas fa-times-circle fas fa-lg close_upload_image\"> </button>\
<button id=\"pause_upload_image\" class=\"fas fa-pause fas fa-lg pause_upload_image\"> </button>\
<button id=\"play_upload_image\" class=\"fas fa-play fas fa-lg play_upload_image\" hidden=\"true\"> </button>\
</div>\
</div>\
<div class=\"medium-2 columns\">\
<div id=\"speed\">speed: </div>\
<div id=\"percent_progress\">Completed: </div>\
</div>\
</div>");
}
$(".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;
}
});

View File

@ -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

View File

@ -17,8 +17,8 @@
<form data-abide novalidate id="{{formPanelId}}Advanced" class="custom creation">
<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>
<label for="{{prepend}}_datastores_raw">{{tr "Datastore"}}</label>
<div id="{{prepend}}_datastore_raw" name="{{prepend}}_datastore_raw"></div>
</div>
</div>
<div class="row">

View File

@ -15,5 +15,5 @@
/* -------------------------------------------------------------------------- */
define(function(require){
return 'createFileForm';
return "createFileForm";
});

View File

@ -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. }}
{{! -------------------------------------------------------------------------- }}
<form data-abide novalidate id="{{formPanelId}}Wizard" class="custom creation">
<div class="row">
<div class="medium-4 columns">
<label for="{{prepend}}_name">
{{tr "Name"}}
</label>
<input required type="text" name="{{prepend}}_name" id="{{prepend}}_name" />
</div>
<div class="medium-8 columns">
<label for="{{prepend}}_desc">
{{tr "Description"}}
</label>
<textarea name="{{prepend}}_desc" id="{{prepend}}_desc" rows="4"></textarea>
</div>
</div>
<div class="row">
<div class="medium-4 columns">
<label for="{{prepend}}_type">
{{tr "Type"}}
</label>
<select name="{{prepend}}_type" id="{{prepend}}_type">
<option value="CONTEXT">{{tr "Context"}}</option>
<option value="KERNEL">{{tr "Kernel"}}</option>
<option value="RAMDISK">{{tr "Ramdisk"}}</option>
</select>
</div>
<div class="medium-8 columns">
<label for="{{prepend}}_datastore">
{{tr "Datastore"}}
</label>
<div id="{{prepend}}_datastore" name="{{prepend}}_datastore"></div>
</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 "Path/URL"}}</label>
<input type="radio" name="src_path" id="upload_image" value="upload">
<label for="upload_image">{{tr "Upload"}}</label>
</div>
</div>
<br>
<div class="row">
<div class="large-12 columns">
<label for="img_path">
{{tr "Path in OpenNebula server or URL"}}
</label>
<input type="text" name="{{prepend}}_path" id="{{prepend}}_path" />
</div>
</div>
<div class="row">
<div id="file-uploader" class="large-12 columns text-center">
<label id="file-uploader-label" for="file-uploader-input"></label>
<i id="close_image" class="fas fa-times-circle fas fa-lg close_image" hidden="true"></i>
<input id="file-uploader-input" type="file"/>
</div>
</div>
<div class="{{prepend}}_size row">
<div class="medium-6 columns">
<label for="{{prepend}}_size">
{{tr "Size"}}
</label>
<div class="input-group mb_input_wrapper">
<div class="input-group-field">
<input type="text" name="{{prepend}}_size" id="{{prepend}}_size" />
</div>
<div class="input-group-button">
<select class="mb_input_unit">
<option value="MB">{{tr "MB"}}</option>
<option value="GB" selected>{{tr "GB"}}</option>
</select>
</div>
</div>
</div>
<div class="medium-6 columns only_vcenter">
<label for="vcenter_disk_type">
{{tr "Disk provisioning type"}}
</label>
<select name="vcenter_disk_type" id="vcenter_disk_type">
<option value="" selected="selected"></option>
<option value="thin">Thin</option>
<option value="thick">Thick</option>
<option value="eagerZeroedThick">Eager Zeroed Thick</option>
<option value="custom">custom</option>
</select>
<div>
<input type="text" id="custom_vcenter_disk_type" name="custom_vcenter_disk_type" />
</div>
</div>
</div>
</fieldset>
</form>

View File

@ -15,5 +15,5 @@
/* -------------------------------------------------------------------------- */
define(function(require){
return 'files-tab';
})
return "files-tab";
});

View File

@ -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(
"<div id=\"" + fileName + "progressBar\" class=\"row\" style=\"margin-bottom:10px\">\
<div id=\"" + fileName + "-info\" class=\"medium-2 columns\">\
" + Locale.tr("Uploading...") + "\
</div>\
<div class=\"medium-10 columns\">\
<div class=\"progressbar\">"+
ProgressBar.html(0, 1, fileName) + "\
</div>\
<div>\
<button id=\"close_upload_image\" class=\"fas fa-times-circle fas fa-lg close_upload_image\"> </button>\
<button id=\"pause_upload_image\" class=\"fas fa-pause fas fa-lg pause_upload_image\"> </button>\
<button id=\"play_upload_image\" class=\"fas fa-play fas fa-lg play_upload_image\" hidden=\"true\"> </button>\
</div>\
</div>\
<div class=\"medium-2 columns\">\
<div id=\"speed\">speed: </div>\
<div id=\"percent_progress\">Completed: </div>\
</div>\
</div>");
}
$(".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;
}

View File

@ -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

View File

@ -15,5 +15,5 @@
/* -------------------------------------------------------------------------- */
define(function(require){
return 'createImageForm';
})
return "createImageForm";
});

View File

@ -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. }}
{{! -------------------------------------------------------------------------- }}
<div>
<dl id="{{formPanelId}}Tabs" class="tabs sunstone-info-tabs" data-tabs>
{{#each wizardTabs}}
<dd class='tabs-title {{classes}}'>
<a href='#{{wizardTabId}}' class="changeTypeSender"
{{#if typeSender}}
data-typesender={{typeSender}}
{{/if}}
>
<i class='fa {{icon}}'></i>
<br>{{title}}
</a>
</dd>
{{/each}}
</dl>
<div class="tabs-content" data-tabs-content="{{formPanelId}}Tabs">
{{#each wizardTabs}}
<div id="{{wizardTabId}}" class="wizard_tab tabs-panel">
{{{contentHTML}}}
</div>
{{/each}}
</div>
</div>

View File

@ -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");
}
});

View File

@ -0,0 +1,37 @@
<form data-abide novalidate id="{{formPanelId}}Docker" class="custom creation">
<div class="row">
<div class="columns large-6">
<label for="{{prepend}}_name">{{tr "Name"}}</label>
<input required type="text" name="{{prepend}}_name" id="{{prepend}}_name" />
</div>
<div class="columns large-6">
<label for="{{prepend}}_datastore">{{tr "Datastore"}}</label>
<div id="{{prepend}}_datastore" name="{{prepend}}_datastore"></div>
</div>
</div>
<div class="row">
<div class="large-6 columns">
<label for="{{prepend}}_context">{{tr "Context"}}</label>
<select id="{{prepend}}_context">
<option value="yes"> {{tr "YES"}}</option>
<option value="no"> {{tr "NO"}}</option>
</select>
</div>
<div class="columns large-6">
<label for="{{prepend}}_size">{{tr "Size"}}</label>
<div style="display:flex;">
<input required type="text" name="{{prepend}}_size" id="{{prepend}}_size" />
<select id="{{prepend}}_size_units" style="max-width: 60px;">
<option value="1"> {{tr "MB"}}</option>
<option value="1024"> {{tr "GB"}}</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<p>{{tr "Write the Dockerfile template here"}}</p>
<div id="{{prepend}}_template" class="monospace" style="height: 500px; width: 100%"> </div>
</div>
</div>
</form>

View File

@ -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";
});

View File

@ -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(
"<div id=\"" + fileName + "progressBar\" class=\"row\" style=\"margin-bottom:10px\">\
<div id=\"" + fileName + "-info\" class=\"medium-2 columns\">\
" + Locale.tr("Uploading...") + "\
</div>\
<div class=\"medium-10 columns\">\
<div class=\"progressbar\">"+
ProgressBar.html(0, 1, fileName) + "\
</div>\
<div>\
<button id=\"close_upload_image\" class=\"fas fa-times-circle fas fa-lg close_upload_image\"> </button>\
<button id=\"pause_upload_image\" class=\"fas fa-pause fas fa-lg pause_upload_image\"> </button>\
<button id=\"play_upload_image\" class=\"fas fa-play fas fa-lg play_upload_image\" hidden=\"true\"> </button>\
</div>\
</div>\
<div class=\"medium-2 columns\">\
<div id=\"speed\">speed: </div>\
<div id=\"percent_progress\">Completed: </div>\
</div>\
</div>");
}
$(".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) {
}
});

View File

@ -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. }}
{{! -------------------------------------------------------------------------- }}
<form data-abide novalidate id="{{formPanelId}}Advanced" class="tabs-panel custom creation">
<div class="row">
<div class="columns large-12">
<label for="{{prepend}}_datastores_raw">{{tr "Datastore"}}</label>
<div id="{{prepend}}_datastore_raw_advanced" name="{{prepend}}_datastore_raw"></div>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<p>{{tr "Write the Image template here"}}</p>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<textarea id="template" class="monospace" rows="15" required></textarea>
</div>
</div>
</form>

View File

@ -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. }}
{{! -------------------------------------------------------------------------- }}
<form data-abide novalidate id="{{formPanelId}}Wizard" class="custom creation">
<form data-abide novalidate id="{{formPanelId}}Wizard" class="tabs-panel is-active custom creation">
<div class="row">
<div class="medium-4 columns">
<label for="img_name">
<label for="{{prepend}}_name">
{{tr "Name"}}
</label>
<input required type="text" name="img_name" id="img_name" />
<input required type="text" name="{{prepend}}_name" id="{{prepend}}_name" />
</div>
<div class="medium-8 columns">
<label for="img_desc">
<label for="{{prepend}}_desc">
{{tr "Description"}}
</label>
<textarea name="img_desc" id="img_desc" rows="4"></textarea>
<textarea name="{{prepend}}_desc" id="{{prepend}}_desc" rows="4"></textarea>
</div>
</div>
<div class="row">
<div class="medium-4 columns">
<label for="img_type">
<label for="{{prepend}}_type">
{{tr "Type"}}
</label>
<select name="img_type" id="img_type">
{{#if images}}
<select name="{{prepend}}_type" id="{{prepend}}_type">
<option value="OS">{{tr "Operating System image"}}</option>
<option value="CDROM">{{tr "Readonly CD-ROM"}}</option>
<option value="DATABLOCK">{{tr "Generic storage datablock"}}</option>
{{else}}
<option value="CONTEXT">{{tr "Context"}}</option>
<option value="KERNEL">{{tr "Kernel"}}</option>
<option value="RAMDISK">{{tr "Ramdisk"}}</option>
{{/if}}
</select>
</div>
<div class="medium-8 columns">
<label for="img_datastore">
<label for="{{prepend}}_datastore">
{{tr "Datastore"}}
</label>
<div id="img_datastore" name="img_datastore"></div>
<div id="{{prepend}}_datastore" name="{{prepend}}_datastore"></div>
</div>
</div>
{{#if images}}
{{#isTabActionEnabled "images-tab" "Image.persistent"}}
<div class="row">
<div class="large-4 columns">
@ -64,7 +57,7 @@
</label>
</div>
<div class="large-4 columns">
<select id="img_persistent">
<select id="{{prepend}}_persistent">
<option value=""></option>
<option value="YES"> {{tr "YES"}}</option>
<option value="NO"> {{tr "NO"}}</option>
@ -74,7 +67,6 @@
</div>
</div>
{{/isTabActionEnabled}}
{{/if}}
<br>
<fieldset>
<legend>{{tr "Image location"}}</legend>
@ -84,19 +76,17 @@
<label for="path_image">{{tr "Path/URL"}}</label>
<input type="radio" name="src_path" id="upload_image" value="upload">
<label for="upload_image">{{tr "Upload"}}</label>
{{#if images}}
<input type="radio" name="src_path" id="datablock_img" value="datablock">
<label for="datablock_img">{{tr "Empty disk image"}}</label>
{{/if}}
</div>
</div>
<br>
<div class="row">
<div class="large-12 columns">
<label for="img_path">
<label for="{{prepend}}_path">
{{tr "Path in OpenNebula server or URL"}}
</label>
<input type="text" name="img_path" id="img_path" />
<input type="text" name="{{prepend}}_path" id="{{prepend}}_path" />
</div>
</div>
<div class="row">
@ -106,14 +96,14 @@
<input id="file-uploader-input" type="file"/>
</div>
</div>
<div class="img_size row">
<div class="{{prepend}}_size row">
<div class="medium-6 columns">
<label for="img_size">
<label for="{{prepend}}_size">
{{tr "Size"}}
</label>
<div class="input-group mb_input_wrapper">
<div class="input-group-field">
<input type="text" name="img_size" id="img_size" />
<input type="text" name="{{prepend}}_size" id="{{prepend}}_size" />
</div>
<div class="input-group-button">
<select class="mb_input_unit">
@ -140,7 +130,6 @@
</div>
</div>
</fieldset>
{{#if images}}
{{#advancedSection (tr "Advanced Options") }}
<div class="row">
<div class="medium-6 columns">
@ -163,10 +152,10 @@
</div>
<div class="row not_vcenter">
<div class="large-12 columns">
<label for="img_dev_prefix">
<label for="{{prepend}}_dev_prefix">
{{tr "BUS"}}
</label>
<select name="img_dev_prefix" id="img_dev_prefix">
<select name="{{prepend}}_dev_prefix" id="{{prepend}}_dev_prefix">
<option value="" selected="selected"></option>
<option value="vd">Virtio</option>
<option value="sd">SCSI/SATA</option>
@ -174,23 +163,23 @@
<option value="custom">custom</option>
</select>
<div>
<input type="text" id="custom_img_dev_prefix" name="custom_img_dev_prefix" />
<input type="text" id="custom_{{prepend}}_dev_prefix" name="custom_{{prepend}}_dev_prefix" />
</div>
</div>
</div>
<div class="row not_vcenter">
<div class="large-12 columns datablock-input">
<label for="img_driver">
<label for="{{prepend}}_driver">
{{tr "Format"}}
</label>
<select name="img_driver" id="img_driver">
<select name="{{prepend}}_driver" id="{{prepend}}_driver">
<option value="" selected="selected">--</option>
<option value="raw">raw</option>
<option value="qcow2">qcow2</option>
<option value="custom">custom</option>
</select>
<div>
<input type="text" id="custom_img_driver" name="custom_img_driver" />
<input type="text" id="custom_{{prepend}}_driver" name="custom_{{prepend}}_driver" />
</div>
</div>
</div>
@ -198,10 +187,10 @@
<div class="medium-6 columns">
<div class="row not_vcenter">
<div class="large-12 columns">
<label for="img_target">
<label for="{{prepend}}_target">
{{tr "Target device"}}
</label>
<input type="text" name="img_target" id="img_target" />
<input type="text" name="{{prepend}}_target" id="{{prepend}}_target" />
</div>
</div>
</div>
@ -216,5 +205,4 @@
{{{customTagsHTML}}}
</fieldset>
{{/advancedSection}}
{{/if}}
</form>

View File

@ -0,0 +1,20 @@
/* -------------------------------------------------------------------------- */
/* 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 "imageCreateTab";
});

View File

@ -0,0 +1,43 @@
{{! -------------------------------------------------------------------------- }}
{{! 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. }}
{{! -------------------------------------------------------------------------- }}
<div class="small-12 columns">
{{#if advanced}}
<span class="internal-form-tabs">
<ul id="{{formPanelId}}InternalTabs" class="tabs wizard_tabs show" data-tabs style="display: flex;justify-content: flex-end;border-bottom: 0px;">
<li class="tabs-title is-active">
<a href="#{{formPanelId}}Wizard" class="changeTypeSender" data-typesender="wizard">
{{tr "Wizard"}}
</a>
</li>
<li id="advanced_mode" class="tabs-title">
<a href="#{{formPanelId}}Advanced" class="changeTypeSender" data-typesender="advanced">
{{tr "Advanced"}}
</a>
</li>
</ul>
</span>
{{/if}}
<div class="tabs-content" data-tabs-content="{{formPanelId}}InternalTabs">
{{#if form}}
{{{form}}}
{{/if}}
{{#if advanced}}
{{{advanced}}}
{{/if}}
</div>
</div>

View File

@ -15,5 +15,5 @@
/* -------------------------------------------------------------------------- */
define(function(require){
return 'images-tab';
})
return "images-tab";
});

View File

@ -22,7 +22,8 @@
"guacamole-common-js": "https://github.com/OpenNebula/sunstone-deps.git#1633556e63",
"webauthn-json": "https://registry.npmjs.org/@github/webauthn-json/-/webauthn-json-0.4.1.tgz",
"wmks": "https://github.com/OpenNebula/sunstone-deps.git#cb0251c",
"socket.io-client": "~2.3.0"
"socket.io-client": "~2.3.0",
"ace-builds": "https://github.com/OpenNebula/sunstone-deps.git#01ae12a"
},
"authors": [
"Daniel Molina <dmolina@opennebula.org>",