diff --git a/src/sunstone/models/OpenNebulaJSON.rb b/src/sunstone/models/OpenNebulaJSON.rb
index 9fb45fac7d..cfdb0d162e 100644
--- a/src/sunstone/models/OpenNebulaJSON.rb
+++ b/src/sunstone/models/OpenNebulaJSON.rb
@@ -20,6 +20,7 @@ include OpenNebula
require 'OpenNebulaJSON/ClusterJSON'
require 'OpenNebulaJSON/HostJSON'
require 'OpenNebulaJSON/ImageJSON'
+require 'OpenNebulaJSON/TemplateJSON'
require 'OpenNebulaJSON/JSONUtils'
require 'OpenNebulaJSON/PoolJSON'
require 'OpenNebulaJSON/UserJSON'
diff --git a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb
index d32241c5d7..4ed254cbe6 100644
--- a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb
+++ b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb
@@ -21,6 +21,7 @@ module OpenNebulaJSON
class VirtualMachinePoolJSON < OpenNebula::VirtualMachinePool; include JSONUtils; end
class VirtualNetworkPoolJSON < OpenNebula::VirtualNetworkPool; include JSONUtils; end
class ImagePoolJSON < OpenNebula::ImagePool; include JSONUtils; end
+ class TemplatePoolJSON < OpenNebula::TemplatePool; include JSONUtils; end
class ClusterPoolJSON < OpenNebula::ClusterPool; include JSONUtils; end
class UserPoolJSON < OpenNebula::UserPool; include JSONUtils; end
end
diff --git a/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb b/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb
new file mode 100644
index 0000000000..7ce484f82d
--- /dev/null
+++ b/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb
@@ -0,0 +1,65 @@
+# -------------------------------------------------------------------------- #
+# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
+# #
+# 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. #
+#--------------------------------------------------------------------------- #
+
+require 'OpenNebulaJSON/JSONUtils'
+
+module OpenNebulaJSON
+ class TemplateJSON < OpenNebula::Template
+ include JSONUtils
+
+ def create(template_json)
+ template_hash = parse_json(template_json, 'vmtemplate')
+ if OpenNebula.is_error?(template_hash)
+ return template_hash
+ end
+
+ if template_hash['template_raw']
+ template = template_hash['template_raw']
+ else
+ template = template_to_str(template_hash)
+ end
+
+ self.allocate(template)
+ end
+
+ def perform_action(template_json)
+ action_hash = parse_json(template_json, 'action')
+ if OpenNebula.is_error?(action_hash)
+ return action_hash
+ end
+
+ rc = case action_hash['perform']
+ when "publish" then self.publish
+ when "rm_attr" then self.remove_attr(action_hash['params'])
+ when "unpublish" then self.unpublish
+ when "update" then self.update(action_hash['params'])
+ else
+ error_msg = "#{action_hash['perform']} action not " <<
+ " available for this resource"
+ OpenNebula::Error.new(error_msg)
+ end
+
+ end
+
+ def update(params=Hash.new)
+ super(params['name'], params['value'])
+ end
+
+ def remove_attr(params=Hash.new)
+ super(params['name'])
+ end
+ end
+end
diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb
index 55f6cada51..7b04a7b923 100644
--- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb
+++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb
@@ -28,6 +28,12 @@ module OpenNebulaJSON
if vm_hash['vm_raw']
template = vm_hash['vm_raw']
+ elsif vm_hash['template_id']
+ template_id = vm_hash['template_id']
+
+ template = "TEMPLATE_ID = #{template_id}"
+ template << "\nNAME = #{vm_hash[:vm_name]}" if vm_hash[:vm_name]
+
else
template = template_to_str(vm_hash)
end
@@ -55,7 +61,7 @@ module OpenNebulaJSON
when "restart" then self.restart
when "saveas" then self.save_as(action_hash['params'])
when "shutdown" then self.shutdown
- when "resubmit" then self.resubmit
+ when "resubmit" then self.resubmit
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb
index ea690c33a9..c79854694d 100644
--- a/src/sunstone/models/SunstoneServer.rb
+++ b/src/sunstone/models/SunstoneServer.rb
@@ -68,12 +68,13 @@ class SunstoneServer
def get_pool(kind)
user_flag = -2
pool = case kind
- when "cluster" then ClusterPoolJSON.new(@client)
- when "host" then HostPoolJSON.new(@client)
- when "image" then ImagePoolJSON.new(@client, user_flag)
- when "vm" then VirtualMachinePoolJSON.new(@client, user_flag)
- when "vnet" then VirtualNetworkPoolJSON.new(@client, user_flag)
- when "user" then UserPoolJSON.new(@client)
+ when "cluster" then ClusterPoolJSON.new(@client)
+ when "host" then HostPoolJSON.new(@client)
+ when "image" then ImagePoolJSON.new(@client, user_flag)
+ when "template" then TemplatePoolJSON.new(@client, user_flag)
+ when "vm" then VirtualMachinePoolJSON.new(@client, user_flag)
+ when "vnet" then VirtualNetworkPoolJSON.new(@client, user_flag)
+ when "user" then UserPoolJSON.new(@client)
else
error = Error.new("Error: #{kind} resource not supported")
return [404, error.to_json]
@@ -104,12 +105,13 @@ class SunstoneServer
############################################################################
def create_resource(kind, template)
resource = case kind
- when "cluster" then ClusterJSON.new(Cluster.build_xml, @client)
- when "host" then HostJSON.new(Host.build_xml, @client)
- when "image" then ImageJSON.new(Image.build_xml, @client)
- when "vm" then VirtualMachineJSON.new(VirtualMachine.build_xml,@client)
- when "vnet" then VirtualNetworkJSON.new(VirtualNetwork.build_xml, @client)
- when "user" then UserJSON.new(User.build_xml, @client)
+ when "cluster" then ClusterJSON.new(Cluster.build_xml, @client)
+ when "host" then HostJSON.new(Host.build_xml, @client)
+ when "image" then ImageJSON.new(Image.build_xml, @client)
+ when "template" then TemplateJSON.new(Template.build_xml, @client)
+ when "vm" then VirtualMachineJSON.new(VirtualMachine.build_xml,@client)
+ when "vnet" then VirtualNetworkJSON.new(VirtualNetwork.build_xml, @client)
+ when "user" then UserJSON.new(User.build_xml, @client)
else
error = Error.new("Error: #{kind} resource not supported")
return [404, error.to_json]
@@ -217,12 +219,13 @@ class SunstoneServer
def retrieve_resource(kind, id)
resource = case kind
- when "cluster" then ClusterJSON.new_with_id(id, @client)
- when "host" then HostJSON.new_with_id(id, @client)
- when "image" then ImageJSON.new_with_id(id, @client)
- when "vm" then VirtualMachineJSON.new_with_id(id, @client)
- when "vnet" then VirtualNetworkJSON.new_with_id(id, @client)
- when "user" then UserJSON.new_with_id(id, @client)
+ when "cluster" then ClusterJSON.new_with_id(id, @client)
+ when "host" then HostJSON.new_with_id(id, @client)
+ when "image" then ImageJSON.new_with_id(id, @client)
+ when "template" then TemplateJSON.new_with_id(id, @client)
+ when "vm" then VirtualMachineJSON.new_with_id(id, @client)
+ when "vnet" then VirtualNetworkJSON.new_with_id(id, @client)
+ when "user" then UserJSON.new_with_id(id, @client)
else
error = Error.new("Error: #{kind} resource not supported")
return error
diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js
index ce40c52746..904492f964 100644
--- a/src/sunstone/public/js/opennebula.js
+++ b/src/sunstone/public/js/opennebula.js
@@ -142,7 +142,7 @@ var OpenNebula = {
{
return Error('Incorrect Pool');
}
-
+
var p_pool = [];
if (response[pool_name]) {
@@ -1931,5 +1931,301 @@ var OpenNebula = {
}
});
}
+ },
+
+ "Template" : {
+ "resource" : "VMTEMPLATE",
+
+ "create" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var data = params.data;
+ var resource = OpenNebula.Template.resource;
+
+ var request = OpenNebula.Helper.request(resource,"create",data);
+
+ $.ajax({
+ url: "/template",
+ type: "POST",
+ dataType: "json",
+ data: JSON.stringify(data),
+ success: function(response)
+ {
+ if (callback)
+ {
+ callback(request, response);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+
+ },
+ "addattr" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+ var name = params.data.name;
+ var value = params.data.value;
+
+ var method = "update";
+ var action = OpenNebula.Helper.action(method, {
+ "name" : name,
+ "value" : value
+ });
+
+ var resource = OpenNebula.Template.resource;
+ var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
+
+ $.ajax({
+ url: "/template/" + id + "/action",
+ type: "POST",
+ data: JSON.stringify(action),
+ success: function(response)
+ {
+ if (callback)
+ {
+ callback(request, response);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ },
+ "update" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+ var name = params.data.name;
+ var value = params.data.value;
+
+ var method = "update";
+ var action = OpenNebula.Helper.action(method, {
+ "name" : name,
+ "value" : value
+ });
+
+ var resource = OpenNebula.Template.resource;
+ var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
+
+ $.ajax({
+ url: "/template/" + id + "/action",
+ type: "POST",
+ data: JSON.stringify(action),
+ success: function(response)
+ {
+ if (callback)
+ {
+ callback(request, response);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ },
+ "rmattr" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+ var name = params.data.name;
+ var value = params.data.value;
+
+ var method = "rm_attr";
+ var action = OpenNebula.Helper.action(method, {
+ "name" : name
+ });
+
+ var resource = OpenNebula.Template.resource;
+ var request = OpenNebula.Helper.request(resource,method, [id, name]);
+
+ $.ajax({
+ url: "/template/" + id + "/action",
+ type: "POST",
+ data: JSON.stringify(action),
+ success: function(response)
+ {
+ if (callback)
+ {
+ callback(request, response);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ },
+ "publish" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+
+ var method = "publish";
+ var action = OpenNebula.Helper.action(method);
+ var resource = OpenNebula.Template.resource;
+ var request = OpenNebula.Helper.request(resource,method, id);
+
+ $.ajax({
+ url: "/template/" + id + "/action",
+ type: "POST",
+ data: JSON.stringify(action),
+ success: function()
+ {
+ if (callback)
+ {
+ callback(request);
+ }
+ },
+ error: function(response)
+ {
+ if(callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ },
+ "unpublish" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+
+ var method = "unpublish";
+ var action = OpenNebula.Helper.action(method);
+ var resource = OpenNebula.Template.resource;
+ var request = OpenNebula.Helper.request(resource,method, id);
+
+ $.ajax({
+ url: "/template/" + id + "/action",
+ type: "POST",
+ data: JSON.stringify(action),
+ success: function()
+ {
+ if (callback)
+ {
+ callback(request);
+ }
+ },
+ error: function(response)
+ {
+ if(callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ },
+ "list" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var timeout = params.timeout || false;
+
+ var resource = OpenNebula.Template.resource;
+ var request = OpenNebula.Helper.request(resource,"list");
+
+ $.ajax({
+ url: "/template",
+ type: "GET",
+ dataType: "json",
+ data: {timeout: timeout},
+ success: function(response)
+ {
+ if (callback)
+ {
+ var template_pool = OpenNebula.Helper.pool(resource,response);
+ callback(request, template_pool);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ },
+ "show" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+
+ var resource = OpenNebula.Template.resource;
+ var request = OpenNebula.Helper.request(resource,"show", id);
+
+ $.ajax({
+ url: "/template/" + id,
+ type: "GET",
+ dataType: "json",
+ success: function(response)
+ {
+ if (callback)
+ {
+ callback(request, response);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ },
+ "delete" : function(params)
+ {
+ var callback = params.success;
+ var callback_error = params.error;
+ var id = params.data.id;
+ var resource = OpenNebula.Template.resource;
+
+ var request = OpenNebula.Helper.request(resource,"delete", id);
+
+ $.ajax({
+ url: "/template/" + id,
+ type: "DELETE",
+ success: function()
+ {
+ if (callback)
+ {
+ callback(request);
+ }
+ },
+ error: function(response)
+ {
+ if (callback_error)
+ {
+ callback_error(request, OpenNebula.Error(response));
+ }
+ }
+ });
+ }
}
}
diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js
new file mode 100644
index 0000000000..cb558aa5c7
--- /dev/null
+++ b/src/sunstone/public/js/plugins/templates-tab.js
@@ -0,0 +1,1714 @@
+/* -------------------------------------------------------------------------- */
+/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
+/* */
+/* 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. */
+/* -------------------------------------------------------------------------- */
+
+/*Templates tab plugin*/
+
+var templates_tab_content =
+'
';
+
+var create_template_tmpl = '';
+
+var templates_select = "";
+var template_list_json = {};
+var dataTable_templates;
+
+var template_actions = {
+
+ "Template.create" : {
+ type: "create",
+ call: OpenNebula.Template.create,
+ callback: addTemplateElement,
+ error: onError,
+ notify:true
+ },
+
+ "Template.create_dialog" : {
+ type: "custom",
+ call: popUpCreateTemplateDialog
+ },
+
+ "Template.list" : {
+ type: "list",
+ call: OpenNebula.Template.list,
+ callback: updateTemplatesView,
+ error: onError
+ },
+
+ "Template.show" : {
+ type : "single",
+ call: OpenNebula.Template.show,
+ callback: updateTemplateElement,
+ error: onError
+ },
+
+ "Template.showinfo" : {
+ type: "single",
+ call: OpenNebula.Template.show,
+ callback: updateTemplateInfo,
+ error: onError
+ },
+
+ "Template.refresh" : {
+ type: "custom",
+ call: function () {
+ waitingNodes(dataTable_templates);
+ Sunstone.runAction("Template.list");
+ },
+ },
+
+ "Template.autorefresh" : {
+ type: "custom",
+ call: function() {
+ OpenNebula.Template.list({timeout: true, success: updateTemplatesView, error: onError});
+ }
+ },
+
+ "Template.addattr" : {
+ type: "multiple",
+ call: function(obj){
+ var id_attr = obj.data.id;
+ var name = $('#template_attr_name').val();
+ var value = $('#template_attr_value').val();
+ OpenNebula.Template.addattr(
+ {data: {
+ id: id_attr,
+ name: name,
+ value: value
+ },
+ success: obj.success,
+ error: obj.error
+ });
+ },
+ callback : function (req) {
+ Sunstone.runAction("Template.show",req.request.data[0]);
+ },
+ elements: function() { return getSelectedNodes(dataTable_templates); },
+ error: onError,
+ notify: true
+ },
+
+ "Template.addattr_dialog" : {
+ type: "custom",
+ call: popUpTemplateAddattrDialog
+ },
+
+ "Template.updateattr_dialog" : {
+ type: "custom",
+ call: popUpTemplateAddattrDialog
+ },
+
+ "Template.rmattr" : {
+ type: "multiple",
+ call: function(obj){
+ var id_attr = obj.data.id;
+ var name = $('#template_attr_name').val();
+ OpenNebula.Template.rmattr(
+ {data: {
+ id: id_attr,
+ name: name
+ },
+ success: obj.success,
+ error: obj.error
+ });
+ },
+ callback: function (req) {
+ Sunstone.runAction("Template.show",req.request.data[0]);
+ },
+ elements: function() { return getSelectedNodes(dataTable_templates); },
+ error: onError,
+ notify: true
+ },
+
+ "Template.rmattr_dialog" : {
+ type: "custom",
+ call: popUpTemplateRmattrDialog,
+ },
+
+ "Template.publish" : {
+ type: "multiple",
+ call: OpenNebula.Template.publish,
+ callback: function (req) {
+ Sunstone.runAction("Template.show",req.request.data[0]);
+ },
+ elements: function() { return getSelectedNodes(dataTable_templates); },
+ error: onError,
+ notify: true
+ },
+
+ "Template.unpublish" : {
+ type: "multiple",
+ call: OpenNebula.Template.unpublish,
+ callback: function (req) {
+ Sunstone.runAction("Template.show",req.request.data[0]);
+ },
+ elements: function() { return getSelectedNodes(dataTable_templates); },
+ error: onError,
+ notify: true
+ },
+
+ "Template.delete" : {
+ type: "multiple",
+ call: OpenNebula.Template.delete,
+ callback: deleteTemplateElement,
+ elements: function() { return getSelectedNodes(dataTable_templates); },
+ error: onError,
+ notify: true
+ }
+}
+
+
+var template_buttons = {
+ "Template.refresh" : {
+ type: "image",
+ text: "Refresh list",
+ img: "/images/Refresh-icon.png",
+ condition: True
+ },
+ "Template.create_dialog" : {
+ type: "create_dialog",
+ text: "+ New",
+ condition: True
+ },
+ "Template.addattr_dialog" : {
+ type: "action",
+ text: "Add attribute",
+ condition: True
+ },
+ "Template.updateattr_dialog" : {
+ type: "action",
+ text: "Update attribute",
+ condition: True
+ },
+ "Template.rmattr_dialog" : {
+ type: "action",
+ text: "Remove attribute",
+ condition: True
+ },
+ "action_list" : {
+ type: "select",
+ condition: True,
+ actions: {
+ "Template.publish" : {
+ type: "action",
+ text: "Publish",
+ condition: True
+ },
+ "Template.unpublish" : {
+ type: "action",
+ text: "Unpublish",
+ condition: True
+ },
+ }
+ },
+ "Template.delete" : {
+ type: "action",
+ text: "Delete",
+ condition: True
+ }
+}
+
+var template_info_panel = {
+ "template_info_tab" : {
+ title: "Template information",
+ content: ""
+ }
+}
+
+var templates_tab = {
+ title: "Templates",
+ content: templates_tab_content,
+ buttons: template_buttons,
+ condition: True
+}
+
+Sunstone.addActions(template_actions);
+Sunstone.addMainTab('templates_tab',templates_tab);
+Sunstone.addInfoPanel('template_info_panel',template_info_panel);
+
+// Returns an array containing the values of the template_json and ready
+// to be inserted in the dataTable
+function templateElementArray(template_json){
+ var template = template_json.VMTEMPLATE;
+ return [
+ '',
+ template.ID,
+ template.USERNAME ? template.USERNAME : getUserName(template.UID),
+ template.NAME,
+ pretty_time(template.REGTIME),
+ parseInt(template.PUBLIC) ? "yes" : "no"
+ ];
+}
+
+// Set up the listener on the table TDs to show the info panel
+function templateInfoListener(){
+
+ $('#tbodytemplates tr').live("click",function(e){
+ if ($(e.target).is('input')) {return true;}
+ popDialogLoading();
+ var aData = dataTable_templates.fnGetData(this);
+ var id = $(aData[0]).val();
+ Sunstone.runAction("Template.showinfo",id);
+ return false;
+ });
+}
+
+//Updates the select input field with an option for each template
+function updateTemplateSelect(){
+ templates_select = makeSelectOptions(dataTable_templates,1,3,5,"No");
+
+ //update static selectors:
+ $('#create_vm_dialog #template_id').html(templates_select);
+}
+
+// Callback to update an element in the dataTable
+function updateTemplateElement(request, template_json){
+ var id = template_json.VMTEMPLATE.ID;
+ var element = templateElementArray(template_json);
+ updateSingleElement(element,dataTable_templates,'#template_'+id);
+ updateTemplateSelect();
+}
+
+// Callback to remove an element from the dataTable
+function deleteTemplateElement(req){
+ deleteElement(dataTable_templates,'#template_'+req.request.data);
+ updateTemplateSelect();
+}
+
+// Callback to add a template element
+function addTemplateElement(request, template_json){
+ var element = templateElementArray(template_json);
+ addElement(element,dataTable_templates);
+ //NOTE that the select is not updated because newly added templates
+ //are not public
+}
+
+// Callback to refresh the list of templates
+function updateTemplatesView(request, templates_list){
+ template_list_json = templates_list;
+ var template_list_array = [];
+ $.each(template_list_json,function(){
+ template_list_array.push(templateElementArray(this));
+ });
+
+ updateView(template_list_array,dataTable_templates);
+ updateTemplateSelect();
+ updateDashboard("templates",template_list_json);
+
+}
+
+// Prepare the dialog to add/remove/update template attributes
+function setupTemplateAttributesDialogs(){
+
+ //Append to DOM
+ $('div#dialogs').append('');
+
+ //Put HTML in place
+ $('#template_attributes_dialog').html(
+ '');
+
+ $('#template_attributes_dialog').dialog({
+ autoOpen:false,
+ width:400,
+ modal:true,
+ height:220,
+ resizable:false,
+ });
+
+ $('#template_attributes_dialog button').button();
+
+ //Upcase variable names
+ $('#template_attr_name').keyup(function(){
+ $(this).val($(this).val().toUpperCase());
+ });
+
+ $('#template_attributes_dialog #template_attr_proceed').click(function(){
+ $('#template_attributes_dialog').dialog('close');
+ });
+
+ $('#template_attributes_dialog #template_attr_cancel').click(function(){
+ $('#template_attributes_dialog').dialog('close');
+ return false;
+ });
+
+}
+
+// Popup a dialog to add/update an attribute
+function popUpTemplateAddattrDialog(){
+
+ //Show value field and label
+ $('#template_attr_value').show();
+ $('#template_attr_value').prev().show();
+ var desc = "Please write the name and value of the attribute. It will be added or updated in all selected templates:";
+ $('#template_attr_proceed').val("Template.addattr");
+ $('#template_attr_action_desc').html(desc);
+ $('#template_attributes_dialog').dialog('open');
+ return false;
+}
+
+// Popup a dialog to remove an attribute
+function popUpTemplateRmattrDialog(){
+
+ //Hide value field and label
+ $('#template_attr_value').hide();
+ $('#template_attr_value').prev().hide();
+ var desc = "Please type the attribute you want to remove:";
+ $('#template_attr_proceed').val("Template.rmattr");
+ $('#template_attr_action_desc').html(desc);
+ $('#template_attributes_dialog').dialog('open');
+ return false;
+}
+
+// Callback to update the information panel tabs and pop it up
+function updateTemplateInfo(request,template){
+ var template_info = template.VMTEMPLATE;
+ var info_tab = {
+ title: "Template information",
+ content:
+ '\
+ \
+ Template "'+template_info.NAME+'" information |
\
+ \
+ \
+ ID | \
+ '+template_info.ID+' | \
+
\
+ \
+ Name | \
+ '+template_info.NAME+' | \
+
\
+ \
+ Register time | \
+ '+pretty_time(template_info.REGTIME)+' | \
+
\
+ \
+ Public | \
+ '+(parseInt(template_info.PUBLIC) ? "yes" : "no")+' | \
+
\
+
\
+ \
+ Template |
'+
+ prettyPrintJSON(template_info.TEMPLATE)+
+ '
'
+ }
+
+
+ Sunstone.updateInfoPanelTab("template_info_panel","template_info_tab",info_tab);
+
+ Sunstone.popUpInfoPanel("template_info_panel");
+
+}
+
+// Prepare the template creation dialog
+function setupCreateTemplateDialog(){
+ //Helper functions for the dialog operations
+
+ // Called when changing tabs. Since we use the same form for both
+ // KVM, XEN and others we need to do some operation to update it
+ var vmTabChange = function(event,ui){
+ // ui.tab // anchor element of the selected (clicked) tab
+ // ui.panel // element, that contains the selected/clicked tab contents
+ // ui.index // zero-based index of the selected (clicked) tab
+ switch(ui.index){
+ case 0:
+ enable_kvm();
+ break;
+ case 1:
+ enable_xen();
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ }
+ }
+
+ //Using kvm wizard. Updates mandatory tag, optional tags, disable
+ //XEN-only (and others) items, enables KVM items
+ var enable_kvm = function(){
+ man_class="kvm";
+ opt_class="kvm_opt";
+ $(xen_items).attr("disabled","disabled");
+ $(kvm_items).removeAttr("disabled");
+ //$(items+':disabled').hide();
+
+
+ //KVM particularities:
+ // * Add no_type option for disks
+ // * Add driver default option for boot and select it - hide some fields
+ // * Set the raw type to kvm
+ // * Show the inputs section
+ $('div#disks select#TYPE option:selected').removeAttr("selected");
+ $('div#disks select#TYPE').prepend(
+ '');
+ $('div#disks select#TYPE option#no_type').attr("selected","selected");
+
+ $('select#boot_method option').removeAttr("selected");
+ $('select#boot_method option#no_boot').html("Driver default");
+ $('select#boot_method option').removeAttr("selected");
+ $('.kernel, .bootloader', $('div#os_boot_opts')).hide();
+
+ $('div#disks select#BUS').append(
+ '');
+
+
+
+ $('input#TYPE', section_raw).val("kvm");
+
+ $(section_inputs).show();
+ };
+
+ // Using XEN wizard. Update mandatory and optional classes, disable
+ // KVM-only (and other) items, enable XEN fields...
+ enable_xen = function(){
+ man_class="xen";
+ opt_class="xen_opt";
+ $(kvm_items).attr("disabled","disabled");
+ $(kvm_items).css("background","");
+ $(xen_items).removeAttr("disabled");
+ //$(items+':disabled').hide();
+
+
+ // XEN particularities:
+ // * Remove no_type option from disks
+ // * Remove driver default boot method
+ // * Set the raw section to XEN
+ // * Hide the inputs section
+ $('div#disks select#TYPE option#no_type').remove();
+
+ $('select#boot_method option:selected').removeAttr("selected");
+ $('select#boot_method option#no_boot').html("Please choose");
+ $('.kernel, .bootloader', $('div#os_boot_opts')).hide();
+
+ $('div#disks select#BUS option#virtio').remove();
+
+ $('input#TYPE', section_raw).val("xen");
+ $(section_inputs).hide(); //not present for xen
+ };
+
+ //This function checks that all mandatory items within a section
+ //have some value. Returns true if so, false if not.
+ var mandatory_filter = function(context){
+ var man_items = "."+man_class;
+
+ //find enabled mandatory items in this context
+ man_items = $(man_items+' input:visible, '+man_items+' select:visible',context);
+ var r = true;
+
+ //we fail it the item is enabled and has no value
+ $.each(man_items,function(){
+ if ($(this).parents(".vm_param").attr("disabled") ||
+ !($(this).val().length)) {
+ r = false;
+ return false;
+ };
+ });
+ return r;
+
+ };
+
+ //Adds an option element to a multiple select box. Before doing so,
+ //it checks that the desired filter is passed
+ var box_add_element = function(context,box_tag,filter){
+ var value="";
+ var params= $('.vm_param',context);
+ var inputs= $('input:enabled',params);
+ var selects = $('select:enabled',params);
+ var fields = $.merge(inputs,selects);
+
+ //are fields passing the filter?
+ var result = filter();
+ if (!result) {
+ notifyError("There are mandatory parameters missing in this section");
+ return false;
+ }
+
+ value={};
+
+ //With each enabled field we form a JSON object
+ var id = null;
+ $.each(fields,function(){
+ if (!($(this).parents(".vm_param").attr("disabled")) &&
+ $(this).val().length){
+ //Pick up parent's ID if we do not have one
+ id = $(this).attr('id').length ? $(this).attr('id') : $(this).parent().attr('id');
+ value[id] = $(this).val();
+ }
+ });
+ var value_string = JSON.stringify(value);
+ var option= '';
+ $('select'+box_tag,context).append(option);
+ return false;
+ };
+
+ //Removes selected elements from a multiple select box
+ var box_remove_element = function(section_tag,box_tag){
+ var context = $(section_tag);
+ $('select'+box_tag+' :selected',context).remove();
+ return false;
+ };
+
+ //Given the JSON of a VM template (or of a section of it), it crawls
+ //the fields of certain section (context) and add their name and
+ //values to the template JSON.
+ var addSectionJSON = function(template_json,context){
+ var params= $('.vm_param',context);
+ var inputs= $('input:enabled',params);
+ var selects = $('select:enabled',params);
+ var fields = $.merge(inputs,selects);
+
+ fields.each(function(){
+ if (!($(this).parents(".vm_param").attr("disabled"))){ //if ! disabled
+ if ($(this).val().length){ //if has a length
+ template_json[$(this).attr('id')]=$(this).val();
+ }
+ }
+ });
+ }
+
+ // Given an array (usually empty), a section (context) and a tag for
+ // a multiple select in that section, it adds the contents of the
+ // box as objects in the array.
+ // TODO: Make it return a new array?
+ var addBoxJSON = function(array,context,box_tag){
+ $('select'+box_tag+' option',context).each(function(){
+ array.push( JSON.parse($(this).val()) );
+ });
+ }
+
+ //Given an object, removes those elements which are empty
+ //Used to clean up a template JSON before submitting
+ //it to opennebula.js
+ var removeEmptyObjects = function(obj){
+ for (elem in obj){
+ var remove = false;
+ var value = obj[elem];
+ if (value instanceof Array)
+ {
+ if (value.length == 0)
+ remove = true;
+ }
+ else if (value instanceof Object)
+ {
+ var obj_length = 0;
+ for (e in value)
+ obj_length += 1;
+ if (obj_length == 0)
+ remove = true;
+ }
+ else
+ {
+ value = String(value);
+ if (value.length == 0)
+ remove = true;
+ }
+ if (remove)
+ delete obj[elem];
+ }
+ return obj;
+ }
+
+ //Toggles the icon when a section is folded/unfolded
+ var iconToggle = function(){
+ $('.icon_right').toggle(
+ function(e){
+ $('span',e.currentTarget).removeClass("ui-icon-plusthick");
+ $('span',e.currentTarget).addClass("ui-icon-minusthick");
+ },function(e){
+ $('span',e.currentTarget).removeClass("ui-icon-minusthick");
+ $('span',e.currentTarget).addClass("ui-icon-plusthick");
+ });
+ }
+
+ // Set ups the capacity section
+ var capacity_setup = function(){
+ //Actually there is nothing to set up, but it used to be
+ //possible to hide it like others
+ /*
+ $('fieldset',section_capacity).hide();
+ $('#add_capacity',section_capacity).click(function(){
+ $('fieldset',section_capacity).toggle();
+ return false;
+ });
+ */
+
+ }
+
+ //Sets up the OS_BOOT section
+ var os_boot_setup = function(){
+ $('fieldset',section_os_boot).hide();
+ $('.bootloader, .kernel',section_os_boot).hide();
+
+ $('#add_os_boot_opts',section_os_boot).click(function(){
+ $('fieldset',section_os_boot).toggle();
+ return false;
+ });
+
+
+ //Chrome workaround
+ $('#boot_method').change(function(){
+ $(this).trigger("click");
+ });
+
+ //Depending on the boot method we enable/disable some options
+ $('#boot_method',section_os_boot).click(function(){
+ select = $(this).val();
+ switch (select)
+ {
+ case "kernel":
+ $('.bootloader',section_os_boot).hide();
+ $('.bootloader',section_os_boot).attr("disabled","disabled");
+ $('.kernel',section_os_boot).show();
+ $('.kernel',section_os_boot).removeAttr("disabled");
+ break;
+ case "bootloader":
+ $('.kernel',section_os_boot).hide();
+ $('.kernel',section_os_boot).attr("disabled","disabled");
+ $('.bootloader',section_os_boot).show();
+ $('.bootloader',section_os_boot).removeAttr("disabled");
+ break;
+ default:
+ $('.kernel, .bootloader',section_os_boot).hide();
+ $('.kernel, .bootloader',section_os_boot).attr("disabled","disabled");
+ $('.kernel input, .bootloader input',section_os_boot).val("");
+ };
+ });
+ };
+
+ // Sets up the disk section
+ var disks_setup = function(){
+
+ $('fieldset',section_disks).hide();
+ $('.vm_param', section_disks).hide();
+ //$('#image_vs_disk',section_disks).show();
+
+ $('#add_disks', section_disks).click(function(){
+ $('fieldset',section_disks).toggle();
+ return false;
+ });
+
+ //Depending on adding a disk or a image we need to show/hide
+ //different options and make then mandatory or not
+ $('#image_vs_disk input',section_disks).click(function(){
+ //$('fieldset',section_disks).show();
+ $('.vm_param', section_disks).show();
+ var select = $('#image_vs_disk :checked',section_disks).val();
+ switch (select)
+ {
+ case "disk":
+ $('.add_image',section_disks).hide();
+ $('.add_image',section_disks).attr("disabled","disabled");
+ $('.add_disk',section_disks).show();
+ $('.add_disk',section_disks).removeAttr("disabled");
+ $('#TARGET',section_disks).parent().removeClass(opt_class);
+ $('#TARGET',section_disks).parent().addClass(man_class);
+ break;
+ case "image":
+ $('.add_disk',section_disks).hide();
+ $('.add_disk',section_disks).attr("disabled","disabled");
+ $('.add_image',section_disks).show();
+ $('.add_image',section_disks).removeAttr("disabled");
+ $('#TARGET',section_disks).parent().removeClass(man_class);
+ $('#TARGET',section_disks).parent().addClass(opt_class);
+ break;
+ }
+ $('#SIZE',section_disks).parent().hide();
+ $('#SIZE',section_disks).parent().attr("disabled","disabled");
+ $('#FORMAT',section_disks).parent().hide();
+ $('#SIZE',section_disks).parent().attr("disabled","disabled");
+ $('#TYPE :selected',section_disks).removeAttr("selected");
+ });
+
+ //Chrome workaround
+ $('select#TYPE',section_disks).change(function(){
+ $(this).trigger('click');
+ });
+
+ //Depending on the type of disk we need to show/hide
+ //different options and make then mandatory or not
+ $('select#TYPE',section_disks).click(function(){
+ var select = $(this).val();
+ switch (select) {
+ //size,format,target
+ case "swap":
+ //size mandatory
+ $('#SIZE',section_disks).parent().show();
+ $('#SIZE',section_disks).parent().removeAttr("disabled");
+ $('#SIZE',section_disks).parent().removeClass(opt_class);
+ $('#SIZE',section_disks).parent().addClass(man_class);
+
+ //target optional
+ $('#TARGET',section_disks).parent().removeClass(man_class);
+ $('#TARGET',section_disks).parent().addClass(opt_class);
+
+ //format hidden
+ $('#FORMAT',section_disks).parent().hide();
+ $('#FORMAT',section_disks).parent().attr("disabled","disabled");
+ break;
+ case "fs":
+ //size mandatory
+ $('#SIZE',section_disks).parent().show();
+ $('#SIZE',section_disks).parent().removeAttr("disabled");
+ $('#SIZE',section_disks).parent().removeClass(opt_class);
+ $('#SIZE',section_disks).parent().addClass(man_class);
+
+ //target mandatory
+ $('#TARGET',section_disks).parent().removeClass(opt_class);
+ $('#TARGET',section_disks).parent().addClass(man_class);
+
+ //format mandatory
+ $('#FORMAT',section_disks).parent().show();
+ $('#FORMAT',section_disks).parent().removeAttr("disabled");
+ $('#FORMAT',section_disks).parent().removeClass(opt_class);
+ $('#FORMAT',section_disks).parent().addClass(man_class);
+
+ break;
+ case "block":
+ //size shown and optional
+ $('#SIZE',section_disks).parent().show();
+ $('#SIZE',section_disks).parent().removeAttr("disabled");
+ $('#SIZE',section_disks).parent().removeClass(man_class);
+ $('#SIZE',section_disks).parent().addClass(opt_class);
+
+ //target mandatory
+ $('#TARGET',section_disks).parent().removeClass(opt_class);
+ $('#TARGET',section_disks).parent().addClass(man_class);
+
+ //format hidden
+ $('#FORMAT',section_disks).parent().hide();
+ $('#FORMAT',section_disks).parent().attr("disabled","disabled");
+ break;
+ case "floppy":
+ case "disk":
+ case "cdrom":
+ default:
+ //size hidden
+ $('#SIZE',section_disks).parent().hide();
+ $('#SIZE',section_disks).parent().attr("disabled","disabled");
+
+ //target mandatory
+ $('#TARGET',section_disks).parent().removeClass(opt_class);
+ $('#TARGET',section_disks).parent().addClass(man_class);
+
+ //format optional
+ $('#FORMAT',section_disks).parent().hide();
+ $('#FORMAT',section_disks).parent().attr("disabled","disabled");
+ }
+ });
+
+ //Our filter for the disks section fields is the mandatory
+ //filter for this section
+ var diskFilter = function(){
+ return mandatory_filter(section_disks);
+ };
+
+ $('#add_disk_button',section_disks).click(function(){
+ box_add_element(section_disks,'#disks_box',diskFilter);
+ return false;
+ });
+ $('#remove_disk_button',section_disks).click(function(){
+ box_remove_element(section_disks,'#disks_box');
+ return false;
+ });
+ };
+
+ // Sets up the network section
+ var networks_setup = function(){
+
+ $('.vm_param',section_networks).hide();
+ $('fieldset',section_networks).hide();
+
+ $('#add_networks',section_networks).click(function(){
+ $('fieldset',section_networks).toggle();
+ return false;
+ });
+
+ //Depending on adding predefined network or not we show/hide
+ //some fields
+ $('#network_vs_niccfg input',section_networks).click(function(){
+
+ select = $('#network_vs_niccfg :checked',section_networks).val();
+ switch (select) {
+ case "network":
+ $('.niccfg',section_networks).hide();
+ $('.niccfg',section_networks).attr("disabled","disabled");
+ $('.network',section_networks).show();
+ $('.network',section_networks).removeAttr("disabled");
+ break;
+ case "niccfg":
+ $('.network',section_networks).hide();
+ $('.network',section_networks).attr("disabled","disabled");
+ $('.niccfg',section_networks).show();
+ $('.niccfg',section_networks).removeAttr("disabled");
+ break;
+ }
+ });
+
+ //The filter to add a new network checks that we have selected a
+ //network, or that the ip or mac are set
+ //TODO: Improve this check
+ var nicFilter = function(){
+ return mandatory_filter(section_networks);
+ };
+
+ $('#add_nic_button',section_networks).click(function(){
+ box_add_element(section_networks,'#nics_box',nicFilter);
+ return false;
+ });
+ $('#remove_nic_button',section_networks).click(function(){
+ box_remove_element(section_networks,'#nics_box');
+ return false;
+ });
+
+ };
+
+ //Sets up the input section - basicly enabling adding and removing from box
+ var inputs_setup = function() {
+ $('fieldset',section_inputs).hide();
+
+ $('#add_inputs',section_inputs).click(function(){
+ $('fieldset',section_inputs).toggle();
+ return false;
+ });
+
+ $('#add_input_button',section_inputs).click(function(){
+ //no filter
+ box_add_element(section_inputs,'#inputs_box',True);
+ return false;
+ });
+ $('#remove_input_button',section_inputs).click(function(){
+ box_remove_element(section_inputs,'#inputs_box');
+ return false;
+ });
+ };
+
+ //Set up the graphics section
+ var graphics_setup = function(){
+ $('fieldset',section_graphics).hide();
+ $('.vm_param',section_graphics).hide();
+ $('select#TYPE',section_graphics).parent().show();
+
+ $('#add_graphics',section_graphics).click(function(){
+ $('fieldset',section_graphics).toggle();
+ return false;
+ });
+
+ //Chrome workaround
+ $('select#TYPE',section_graphics).change(function(){
+ $(this).trigger("click");
+ });
+ $('select#TYPE',section_graphics).click(function(){
+ g_type = $(this).val();
+ switch (g_type) {
+ case "vnc":
+ $('#LISTEN',section_graphics).parent().show();
+ $('#PORT',section_graphics).parent().show();
+ $('#PASSWD',section_graphics).parent().show();
+ $('#KEYMAP',section_graphics).parent().show();
+ $('#PORT',section_graphics).parent().removeAttr("disabled");
+ $('#PASSWD',section_graphics).parent().removeAttr("disabled");
+ $('#KEYMAP',section_graphics).parent().removeAttr("disabled");
+ break;
+ case "sdl":
+ $('#LISTEN',section_graphics).parent().show();
+ $('#PORT',section_graphics).parent().hide();
+ $('#PASSWD',section_graphics).parent().hide();
+ $('#KEYMAP',section_graphics).parent().hide();
+ $('#PORT',section_graphics).parent().attr("disabled","disabled");
+ $('#PASSWD',section_graphics).parent().attr("disabled","disabled");
+ $('#KEYMAP',section_graphics).parent().attr("disabled","disabled");
+ break;
+ default:
+ $('#LISTEN',section_graphics).parent().hide();
+ $('#PORT',section_graphics).parent().hide();
+ $('#PASSWD',section_graphics).parent().hide();
+ $('#KEYMAP',section_graphics).parent().hide();
+
+ }
+ });
+
+ }
+
+ //Set up the context section - TODO: Apply improvements here...
+ var context_setup = function(){
+ $('fieldset',section_context).hide();
+
+ $('#add_context',section_context).click(function(){
+ $('fieldset',section_context).toggle();
+ return false;
+ });
+
+ $('#add_context_button', section_context).click(function(){
+ var name = $('#var_name',section_context).val();
+ var value = $('#var_value',section_context).val();
+ if (!name.length || !value.length) {
+ notifyError("Context variable name and value must be filled in");
+ return false;
+ }
+ option= '';
+ $('select#context_box',section_context).append(option);
+ return false;
+ });
+
+ $('#remove_context_button', section_context).click(function(){
+ box_remove_element(section_context,'#context_box');
+ return false;
+ });
+
+
+ };
+
+ // Set up the placement section
+ var placement_setup = function(){
+ $('fieldset',section_placement).hide();
+
+ $('#add_placement',section_placement).click(function(){
+ $('fieldset',section_placement).toggle();
+ return false;
+ });
+
+ };
+
+ // Set up the raw section
+ var raw_setup = function(){
+ $('fieldset',section_raw).hide();
+
+ $('#add_raw',section_raw).click(function(){
+ $('fieldset',section_raw).toggle();
+ return false;
+ });
+ };
+
+ //***CREATE VM DIALOG MAIN BODY***
+
+ $('div#dialogs').append('');
+ //Insert HTML in place
+ $('#create_template_dialog').html(create_template_tmpl);
+ //Enable tabs
+ $('#template_create_tabs').tabs({
+ select:vmTabChange
+ });
+
+ //Prepare jquery dialog
+ var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window
+ $('#create_template_dialog').dialog({
+ autoOpen: false,
+ modal: true,
+ width: 700,
+ height: height
+ });
+
+ // Enhace buttons
+ $('#create_template_dialog button').button();
+ // Setup tips200
+ setupTips($('#create_template_dialog'));
+
+ //Enable different icon for folded/unfolded categories
+ iconToggle(); //toogle +/- buttons
+
+ //Sections, used to stay within their scope
+ var section_capacity = $('#capacity');
+ var section_os_boot = $('#os_boot_opts');
+ var section_disks = $('#disks');
+ var section_networks = $('#networks');
+ var section_inputs = $('#inputs');
+ var section_graphics = $('#graphics');
+ var section_context = $('#context');
+ var section_placement = $('#placement');
+ var section_raw = $('#raw');
+
+ //Different selector for items of kvm and xen (mandatory and optional)
+ var items = '.vm_section input,.vm_section select';
+ var kvm_man_items = '.kvm input,.kvm select';
+ var kvm_opt_items = '.kvm_opt input, .kvm_opt select';
+ var kvm_items = kvm_man_items +','+kvm_opt_items;
+ var xen_man_items = '.xen input,.xen select';
+ var xen_opt_items = '.xen_opt input, .xen_opt select';
+ var xen_items = xen_man_items +','+ xen_opt_items;
+
+ //Starting template type, optional items class and mandatory items class
+ var templ_type = "kvm";
+ var opt_class=".kvm_opt";
+ var man_class=".kvm";
+
+ enable_kvm(); //enable all kvm options
+
+ //Fold/unfold all sections button
+ $('#fold_unfold_vm_params').toggle(
+ function(){
+ $('.vm_section fieldset').show();
+ return false;
+ },
+ function(){
+ $('.vm_section fieldset').hide();
+ $('.vm_section fieldset').first().show(); //Show capacity opts
+ return false;
+ });
+
+ //initialise all sections
+ capacity_setup();
+ os_boot_setup();
+ disks_setup();
+ networks_setup();
+ inputs_setup();
+ graphics_setup();
+ context_setup();
+ placement_setup();
+ raw_setup();
+
+ //Process form
+ $('button#create_template_form_easy').click(function(){
+ //validate form
+
+ var vm_json = {};
+
+ //process capacity options
+ var scope = section_capacity;
+
+ if (!mandatory_filter(scope)){
+ notifyError("There are mandatory fields missing in the capacity section");
+ return false;
+ };
+ addSectionJSON(vm_json,scope);
+
+ //process os_boot_opts
+ scope= section_os_boot;
+ switch (templ_type){
+ case "xen":
+ boot_method = $('#boot_method option:selected',scope).val();
+ if (!boot_method.length){
+ notifyError("Xen templates must specify a boot method");
+ return false;}
+ };
+
+ if (!mandatory_filter(scope)){
+ notifyError("There are mandatory fields missing in the OS Boot options section");
+ return false;
+ };
+ vm_json["OS"] = {};
+ addSectionJSON(vm_json["OS"],scope);
+
+ //process disks -> fetch from box
+ scope = section_disks;
+ vm_json["DISK"] = [];
+ addBoxJSON(vm_json["DISK"],scope,'#disks_box');
+
+ //process nics -> fetch from box
+ scope = section_networks;
+ vm_json["NIC"] = [];
+ addBoxJSON(vm_json["NIC"],scope,'#nics_box');
+
+ //process inputs -> fetch from box
+ scope = section_inputs;
+ vm_json["INPUT"] = [];
+ addBoxJSON(vm_json["INPUT"],scope,'#inputs_box');
+
+ //process graphics -> fetch fields with value
+ scope = section_graphics;
+ vm_json["GRAPHICS"] = {};
+ addSectionJSON(vm_json["GRAPHICS"],scope);
+
+ //context
+ scope = section_context;
+ var context = $('#CONTEXT',scope).val();
+ vm_json["CONTEXT"] = {};
+ $('#context_box option',scope).each(function(){
+ name = $(this).attr("name");
+ value = $(this).val();
+ vm_json["CONTEXT"][name]=value;
+ });
+
+ //placement -> fetch with value
+ scope = section_placement;
+ addSectionJSON(vm_json,scope);
+
+ //raw -> if value set type to driver and fetch
+ scope = section_raw;
+ vm_json["RAW"] = {};
+ addSectionJSON(vm_json["RAW"],scope);
+
+ // remove empty elements
+ vm_json = removeEmptyObjects(vm_json);
+
+ //wrap it in the "vmtemplate" object
+ vm_json = {vmtemplate: vm_json};
+
+
+ Sunstone.runAction("Template.create",vm_json);
+
+ $('#create_template_dialog').dialog('close');
+ return false;
+ });
+
+ //Handle manual forms
+ $('button#create_template_form_manual').click(function(){
+ var template = $('#textarea_vm_template').val();
+
+ //wrap it in the "vm" object
+ template = {"vmtemplate": {"template_raw": template}};
+
+ Sunstone.runAction("Template.create",template);
+ $('#create_template_dialog').dialog('close');
+ return false;
+ });
+
+ //Reset form - empty boxes
+ $('button#reset_vm_form').click(function(){
+ $('select#disks_box option',section_disks).remove();
+ $('select#nics_box option',section_networks).remove();
+ $('select#inputs_box option',section_inputs).remove();
+ return true;
+ });
+
+
+
+}
+
+function popUpCreateTemplateDialog(){
+ $('#create_template_dialog').dialog('open');
+}
+
+// Set the autorefresh interval for the datatable
+function setTemplateAutorefresh() {
+ setInterval(function(){
+ var checked = $('input:checked',dataTable_templates.fnGetNodes());
+ var filter = $("#datatable_templates_filter input").attr("value");
+ if (!checked.length && !filter.length){
+ Sunstone.runAction("Template.autorefresh");
+ }
+ },INTERVAL+someTime());
+}
+
+//The DOM is ready at this point
+$(document).ready(function(){
+
+ dataTable_templates = $("#datatable_templates").dataTable({
+ "bJQueryUI": true,
+ "bSortClasses": false,
+ "bAutoWidth":false,
+ "sPaginationType": "full_numbers",
+ "aoColumnDefs": [
+ { "bSortable": false, "aTargets": ["check"] },
+ { "sWidth": "60px", "aTargets": [0,3] },
+ { "sWidth": "35px", "aTargets": [1] },
+ { "sWidth": "100px", "aTargets": [2,3] }
+ ]
+ });
+
+ dataTable_templates.fnClearTable();
+ addElement([
+ spinner,
+ '','','','',''],dataTable_templates);
+ Sunstone.runAction("Template.list");
+
+ setupCreateTemplateDialog();
+ setupTemplateAttributesDialogs();
+ setTemplateAutorefresh();
+
+ initCheckAllBoxes(dataTable_templates);
+ tableCheckboxesListener(dataTable_templates);
+ templateInfoListener();
+
+})
diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js
index 9fbbb65bc5..d42e254b12 100644
--- a/src/sunstone/public/js/plugins/vms-tab.js
+++ b/src/sunstone/public/js/plugins/vms-tab.js
@@ -39,460 +39,23 @@ var vms_tab_content =
\
';
-var create_vm_tmpl =
-'\
-
\
-
\
-
\
-
\
-
\
-
\
+var create_vm_tmpl ='
';
+ \
+
\
+';
var vmachine_list_json = {};
var dataTable_vMachines;
@@ -751,9 +314,11 @@ var vm_buttons = {
},
"VM.create_dialog" : {
- type: "create_dialog",
+ type: "action",
text: "+ New",
- condition: True
+ condition: True,
+ alwaysActive: true,
+
},
"VM.shutdown" : {
@@ -1047,772 +612,36 @@ function updateVMInfo(request,vm){
}
-// Sets up the create-VM dialog and all the processing associated to it,
+// Sets up the create-template dialog and all the processing associated to it,
// which is a lot.
function setupCreateVMDialog(){
- //Helper functions for the dialog operations
-
- // Called when changing tabs. Since we use the same form for both
- // KVM, XEN and others we need to do some operation to update it
- var vmTabChange = function(event,ui){
- // ui.tab // anchor element of the selected (clicked) tab
- // ui.panel // element, that contains the selected/clicked tab contents
- // ui.index // zero-based index of the selected (clicked) tab
- switch(ui.index){
- case 0:
- enable_kvm();
- break;
- case 1:
- enable_xen();
- break;
- case 2:
- break;
- case 3:
- break;
- }
- }
-
- //Using kvm wizard. Updates mandatory tag, optional tags, disable
- //XEN-only (and others) items, enables KVM items
- var enable_kvm = function(){
- man_class="kvm";
- opt_class="kvm_opt";
- $(xen_items).attr("disabled","disabled");
- $(kvm_items).removeAttr("disabled");
- //$(items+':disabled').hide();
-
-
- //KVM particularities:
- // * Add no_type option for disks
- // * Add driver default option for boot and select it - hide some fields
- // * Set the raw type to kvm
- // * Show the inputs section
- $('div#disks select#TYPE option:selected').removeAttr("selected");
- $('div#disks select#TYPE').prepend(
- '
');
- $('div#disks select#TYPE option#no_type').attr("selected","selected");
-
- $('select#boot_method option').removeAttr("selected");
- $('select#boot_method option#no_boot').html("Driver default");
- $('select#boot_method option').removeAttr("selected");
- $('.kernel, .bootloader', $('div#os_boot_opts')).hide();
-
- $('div#disks select#BUS').append(
- '
');
-
-
-
- $('input#TYPE', section_raw).val("kvm");
-
- $(section_inputs).show();
- };
-
- // Using XEN wizard. Update mandatory and optional classes, disable
- // KVM-only (and other) items, enable XEN fields...
- enable_xen = function(){
- man_class="xen";
- opt_class="xen_opt";
- $(kvm_items).attr("disabled","disabled");
- $(kvm_items).css("background","");
- $(xen_items).removeAttr("disabled");
- //$(items+':disabled').hide();
-
-
- // XEN particularities:
- // * Remove no_type option from disks
- // * Remove driver default boot method
- // * Set the raw section to XEN
- // * Hide the inputs section
- $('div#disks select#TYPE option#no_type').remove();
-
- $('select#boot_method option:selected').removeAttr("selected");
- $('select#boot_method option#no_boot').html("Please choose");
- $('.kernel, .bootloader', $('div#os_boot_opts')).hide();
-
- $('div#disks select#BUS option#virtio').remove();
-
- $('input#TYPE', section_raw).val("xen");
- $(section_inputs).hide(); //not present for xen
- };
-
- //This function checks that all mandatory items within a section
- //have some value. Returns true if so, false if not.
- var mandatory_filter = function(context){
- var man_items = "."+man_class;
-
- //find enabled mandatory items in this context
- man_items = $(man_items+' input:visible, '+man_items+' select:visible',context);
- var r = true;
-
- //we fail it the item is enabled and has no value
- $.each(man_items,function(){
- if ($(this).parents(".vm_param").attr("disabled") ||
- !($(this).val().length)) {
- r = false;
- return false;
- };
- });
- return r;
-
- };
-
- //Adds an option element to a multiple select box. Before doing so,
- //it checks that the desired filter is passed
- var box_add_element = function(context,box_tag,filter){
- var value="";
- var params= $('.vm_param',context);
- var inputs= $('input:enabled',params);
- var selects = $('select:enabled',params);
- var fields = $.merge(inputs,selects);
-
- //are fields passing the filter?
- var result = filter();
- if (!result) {
- notifyError("There are mandatory parameters missing in this section");
- return false;
- }
-
- value={};
-
- //With each enabled field we form a JSON object
- var id = null;
- $.each(fields,function(){
- if (!($(this).parents(".vm_param").attr("disabled")) &&
- $(this).val().length){
- //Pick up parent's ID if we do not have one
- id = $(this).attr('id').length ? $(this).attr('id') : $(this).parent().attr('id');
- value[id] = $(this).val();
- }
- });
- var value_string = JSON.stringify(value);
- var option= '
';
- $('select'+box_tag,context).append(option);
- return false;
- };
-
- //Removes selected elements from a multiple select box
- var box_remove_element = function(section_tag,box_tag){
- var context = $(section_tag);
- $('select'+box_tag+' :selected',context).remove();
- return false;
- };
-
- //Given the JSON of a VM template (or of a section of it), it crawls
- //the fields of certain section (context) and add their name and
- //values to the template JSON.
- var addSectionJSON = function(template_json,context){
- var params= $('.vm_param',context);
- var inputs= $('input:enabled',params);
- var selects = $('select:enabled',params);
- var fields = $.merge(inputs,selects);
-
- fields.each(function(){
- if (!($(this).parents(".vm_param").attr("disabled"))){ //if ! disabled
- if ($(this).val().length){ //if has a length
- template_json[$(this).attr('id')]=$(this).val();
- }
- }
- });
- }
-
- // Given an array (usually empty), a section (context) and a tag for
- // a multiple select in that section, it adds the contents of the
- // box as objects in the array.
- // TODO: Make it return a new array?
- var addBoxJSON = function(array,context,box_tag){
- $('select'+box_tag+' option',context).each(function(){
- array.push( JSON.parse($(this).val()) );
- });
- }
-
- //Given an object, removes those elements which are empty
- //Used to clean up a template JSON before submitting
- //it to opennebula.js
- var removeEmptyObjects = function(obj){
- for (elem in obj){
- var remove = false;
- var value = obj[elem];
- if (value instanceof Array)
- {
- if (value.length == 0)
- remove = true;
- }
- else if (value instanceof Object)
- {
- var obj_length = 0;
- for (e in value)
- obj_length += 1;
- if (obj_length == 0)
- remove = true;
- }
- else
- {
- value = String(value);
- if (value.length == 0)
- remove = true;
- }
- if (remove)
- delete obj[elem];
- }
- return obj;
- }
-
- //Toggles the icon when a section is folded/unfolded
- var iconToggle = function(){
- $('.icon_right').toggle(
- function(e){
- $('span',e.currentTarget).removeClass("ui-icon-plusthick");
- $('span',e.currentTarget).addClass("ui-icon-minusthick");
- },function(e){
- $('span',e.currentTarget).removeClass("ui-icon-minusthick");
- $('span',e.currentTarget).addClass("ui-icon-plusthick");
- });
- }
-
- // Set ups the capacity section
- var capacity_setup = function(){
- //Actually there is nothing to set up, but it used to be
- //possible to hide it like others
- /*
- $('fieldset',section_capacity).hide();
- $('#add_capacity',section_capacity).click(function(){
- $('fieldset',section_capacity).toggle();
- return false;
- });
- */
-
- }
-
- //Sets up the OS_BOOT section
- var os_boot_setup = function(){
- $('fieldset',section_os_boot).hide();
- $('.bootloader, .kernel',section_os_boot).hide();
-
- $('#add_os_boot_opts',section_os_boot).click(function(){
- $('fieldset',section_os_boot).toggle();
- return false;
- });
-
-
- //Chrome workaround
- $('#boot_method').change(function(){
- $(this).trigger("click");
- });
-
- //Depending on the boot method we enable/disable some options
- $('#boot_method',section_os_boot).click(function(){
- select = $(this).val();
- switch (select)
- {
- case "kernel":
- $('.bootloader',section_os_boot).hide();
- $('.bootloader',section_os_boot).attr("disabled","disabled");
- $('.kernel',section_os_boot).show();
- $('.kernel',section_os_boot).removeAttr("disabled");
- break;
- case "bootloader":
- $('.kernel',section_os_boot).hide();
- $('.kernel',section_os_boot).attr("disabled","disabled");
- $('.bootloader',section_os_boot).show();
- $('.bootloader',section_os_boot).removeAttr("disabled");
- break;
- default:
- $('.kernel, .bootloader',section_os_boot).hide();
- $('.kernel, .bootloader',section_os_boot).attr("disabled","disabled");
- $('.kernel input, .bootloader input',section_os_boot).val("");
- };
- });
- };
-
- // Sets up the disk section
- var disks_setup = function(){
-
- $('fieldset',section_disks).hide();
- $('.vm_param', section_disks).hide();
- //$('#image_vs_disk',section_disks).show();
-
- $('#add_disks', section_disks).click(function(){
- $('fieldset',section_disks).toggle();
- return false;
- });
-
- //Depending on adding a disk or a image we need to show/hide
- //different options and make then mandatory or not
- $('#image_vs_disk input',section_disks).click(function(){
- //$('fieldset',section_disks).show();
- $('.vm_param', section_disks).show();
- var select = $('#image_vs_disk :checked',section_disks).val();
- switch (select)
- {
- case "disk":
- $('.add_image',section_disks).hide();
- $('.add_image',section_disks).attr("disabled","disabled");
- $('.add_disk',section_disks).show();
- $('.add_disk',section_disks).removeAttr("disabled");
- $('#TARGET',section_disks).parent().removeClass(opt_class);
- $('#TARGET',section_disks).parent().addClass(man_class);
- break;
- case "image":
- $('.add_disk',section_disks).hide();
- $('.add_disk',section_disks).attr("disabled","disabled");
- $('.add_image',section_disks).show();
- $('.add_image',section_disks).removeAttr("disabled");
- $('#TARGET',section_disks).parent().removeClass(man_class);
- $('#TARGET',section_disks).parent().addClass(opt_class);
- break;
- }
- $('#SIZE',section_disks).parent().hide();
- $('#SIZE',section_disks).parent().attr("disabled","disabled");
- $('#FORMAT',section_disks).parent().hide();
- $('#SIZE',section_disks).parent().attr("disabled","disabled");
- $('#TYPE :selected',section_disks).removeAttr("selected");
- });
-
- //Chrome workaround
- $('select#TYPE',section_disks).change(function(){
- $(this).trigger('click');
- });
-
- //Depending on the type of disk we need to show/hide
- //different options and make then mandatory or not
- $('select#TYPE',section_disks).click(function(){
- var select = $(this).val();
- switch (select) {
- //size,format,target
- case "swap":
- //size mandatory
- $('#SIZE',section_disks).parent().show();
- $('#SIZE',section_disks).parent().removeAttr("disabled");
- $('#SIZE',section_disks).parent().removeClass(opt_class);
- $('#SIZE',section_disks).parent().addClass(man_class);
-
- //target optional
- $('#TARGET',section_disks).parent().removeClass(man_class);
- $('#TARGET',section_disks).parent().addClass(opt_class);
-
- //format hidden
- $('#FORMAT',section_disks).parent().hide();
- $('#FORMAT',section_disks).parent().attr("disabled","disabled");
- break;
- case "fs":
- //size mandatory
- $('#SIZE',section_disks).parent().show();
- $('#SIZE',section_disks).parent().removeAttr("disabled");
- $('#SIZE',section_disks).parent().removeClass(opt_class);
- $('#SIZE',section_disks).parent().addClass(man_class);
-
- //target mandatory
- $('#TARGET',section_disks).parent().removeClass(opt_class);
- $('#TARGET',section_disks).parent().addClass(man_class);
-
- //format mandatory
- $('#FORMAT',section_disks).parent().show();
- $('#FORMAT',section_disks).parent().removeAttr("disabled");
- $('#FORMAT',section_disks).parent().removeClass(opt_class);
- $('#FORMAT',section_disks).parent().addClass(man_class);
-
- break;
- case "block":
- //size shown and optional
- $('#SIZE',section_disks).parent().show();
- $('#SIZE',section_disks).parent().removeAttr("disabled");
- $('#SIZE',section_disks).parent().removeClass(man_class);
- $('#SIZE',section_disks).parent().addClass(opt_class);
-
- //target mandatory
- $('#TARGET',section_disks).parent().removeClass(opt_class);
- $('#TARGET',section_disks).parent().addClass(man_class);
-
- //format hidden
- $('#FORMAT',section_disks).parent().hide();
- $('#FORMAT',section_disks).parent().attr("disabled","disabled");
- break;
- case "floppy":
- case "disk":
- case "cdrom":
- default:
- //size hidden
- $('#SIZE',section_disks).parent().hide();
- $('#SIZE',section_disks).parent().attr("disabled","disabled");
-
- //target mandatory
- $('#TARGET',section_disks).parent().removeClass(opt_class);
- $('#TARGET',section_disks).parent().addClass(man_class);
-
- //format optional
- $('#FORMAT',section_disks).parent().hide();
- $('#FORMAT',section_disks).parent().attr("disabled","disabled");
- }
- });
-
- //Our filter for the disks section fields is the mandatory
- //filter for this section
- var diskFilter = function(){
- return mandatory_filter(section_disks);
- };
-
- $('#add_disk_button',section_disks).click(function(){
- box_add_element(section_disks,'#disks_box',diskFilter);
- return false;
- });
- $('#remove_disk_button',section_disks).click(function(){
- box_remove_element(section_disks,'#disks_box');
- return false;
- });
- };
-
- // Sets up the network section
- var networks_setup = function(){
-
- $('.vm_param',section_networks).hide();
- $('fieldset',section_networks).hide();
-
- $('#add_networks',section_networks).click(function(){
- $('fieldset',section_networks).toggle();
- return false;
- });
-
- //Depending on adding predefined network or not we show/hide
- //some fields
- $('#network_vs_niccfg input',section_networks).click(function(){
-
- select = $('#network_vs_niccfg :checked',section_networks).val();
- switch (select) {
- case "network":
- $('.niccfg',section_networks).hide();
- $('.niccfg',section_networks).attr("disabled","disabled");
- $('.network',section_networks).show();
- $('.network',section_networks).removeAttr("disabled");
- break;
- case "niccfg":
- $('.network',section_networks).hide();
- $('.network',section_networks).attr("disabled","disabled");
- $('.niccfg',section_networks).show();
- $('.niccfg',section_networks).removeAttr("disabled");
- break;
- }
- });
-
- //The filter to add a new network checks that we have selected a
- //network, or that the ip or mac are set
- //TODO: Improve this check
- var nicFilter = function(){
- return mandatory_filter(section_networks);
- };
-
- $('#add_nic_button',section_networks).click(function(){
- box_add_element(section_networks,'#nics_box',nicFilter);
- return false;
- });
- $('#remove_nic_button',section_networks).click(function(){
- box_remove_element(section_networks,'#nics_box');
- return false;
- });
-
- };
-
- //Sets up the input section - basicly enabling adding and removing from box
- var inputs_setup = function() {
- $('fieldset',section_inputs).hide();
-
- $('#add_inputs',section_inputs).click(function(){
- $('fieldset',section_inputs).toggle();
- return false;
- });
-
- $('#add_input_button',section_inputs).click(function(){
- //no filter
- box_add_element(section_inputs,'#inputs_box',True);
- return false;
- });
- $('#remove_input_button',section_inputs).click(function(){
- box_remove_element(section_inputs,'#inputs_box');
- return false;
- });
- };
-
- //Set up the graphics section
- var graphics_setup = function(){
- $('fieldset',section_graphics).hide();
- $('.vm_param',section_graphics).hide();
- $('select#TYPE',section_graphics).parent().show();
-
- $('#add_graphics',section_graphics).click(function(){
- $('fieldset',section_graphics).toggle();
- return false;
- });
-
- //Chrome workaround
- $('select#TYPE',section_graphics).change(function(){
- $(this).trigger("click");
- });
- $('select#TYPE',section_graphics).click(function(){
- g_type = $(this).val();
- switch (g_type) {
- case "vnc":
- $('#LISTEN',section_graphics).parent().show();
- $('#PORT',section_graphics).parent().show();
- $('#PASSWD',section_graphics).parent().show();
- $('#KEYMAP',section_graphics).parent().show();
- $('#PORT',section_graphics).parent().removeAttr("disabled");
- $('#PASSWD',section_graphics).parent().removeAttr("disabled");
- $('#KEYMAP',section_graphics).parent().removeAttr("disabled");
- break;
- case "sdl":
- $('#LISTEN',section_graphics).parent().show();
- $('#PORT',section_graphics).parent().hide();
- $('#PASSWD',section_graphics).parent().hide();
- $('#KEYMAP',section_graphics).parent().hide();
- $('#PORT',section_graphics).parent().attr("disabled","disabled");
- $('#PASSWD',section_graphics).parent().attr("disabled","disabled");
- $('#KEYMAP',section_graphics).parent().attr("disabled","disabled");
- break;
- default:
- $('#LISTEN',section_graphics).parent().hide();
- $('#PORT',section_graphics).parent().hide();
- $('#PASSWD',section_graphics).parent().hide();
- $('#KEYMAP',section_graphics).parent().hide();
-
- }
- });
-
- }
-
- //Set up the context section - TODO: Apply improvements here...
- var context_setup = function(){
- $('fieldset',section_context).hide();
-
- $('#add_context',section_context).click(function(){
- $('fieldset',section_context).toggle();
- return false;
- });
-
- $('#add_context_button', section_context).click(function(){
- var name = $('#var_name',section_context).val();
- var value = $('#var_value',section_context).val();
- if (!name.length || !value.length) {
- notifyError("Context variable name and value must be filled in");
- return false;
- }
- option= '
';
- $('select#context_box',section_context).append(option);
- return false;
- });
-
- $('#remove_context_button', section_context).click(function(){
- box_remove_element(section_context,'#context_box');
- return false;
- });
-
-
- };
-
- // Set up the placement section
- var placement_setup = function(){
- $('fieldset',section_placement).hide();
-
- $('#add_placement',section_placement).click(function(){
- $('fieldset',section_placement).toggle();
- return false;
- });
-
- };
-
- // Set up the raw section
- var raw_setup = function(){
- $('fieldset',section_raw).hide();
-
- $('#add_raw',section_raw).click(function(){
- $('fieldset',section_raw).toggle();
- return false;
- });
- };
-
- //***CREATE VM DIALOG MAIN BODY***
-
- $('div#dialogs').append('
');
+ $('div#dialogs').append('
');
//Insert HTML in place
$('#create_vm_dialog').html(create_vm_tmpl);
- //Enable tabs
- $('#vm_create_tabs').tabs({
- select:vmTabChange
- });
//Prepare jquery dialog
- var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window
$('#create_vm_dialog').dialog({
autoOpen: false,
modal: true,
- width: 700,
- height: height
+ width: 400
});
- // Enhace buttons
$('#create_vm_dialog button').button();
- //Enable different icon for folded/unfolded categories
- iconToggle(); //toogle +/- buttons
-
- //Sections, used to stay within their scope
- var section_capacity = $('#capacity');
- var section_os_boot = $('#os_boot_opts');
- var section_disks = $('#disks');
- var section_networks = $('#networks');
- var section_inputs = $('#inputs');
- var section_graphics = $('#graphics');
- var section_context = $('#context');
- var section_placement = $('#placement');
- var section_raw = $('#raw');
-
- //Different selector for items of kvm and xen (mandatory and optional)
- var items = '.vm_section input,.vm_section select';
- var kvm_man_items = '.kvm input,.kvm select';
- var kvm_opt_items = '.kvm_opt input, .kvm_opt select';
- var kvm_items = kvm_man_items +','+kvm_opt_items;
- var xen_man_items = '.xen input,.xen select';
- var xen_opt_items = '.xen_opt input, .xen_opt select';
- var xen_items = xen_man_items +','+ xen_opt_items;
-
- //Starting template type, optional items class and mandatory items class
- var templ_type = "kvm";
- var opt_class=".kvm_opt";
- var man_class=".kvm";
-
- enable_kvm(); //enable all kvm options
-
- //Fold/unfold all sections button
- $('#fold_unfold_vm_params').toggle(
- function(){
- $('.vm_section fieldset').show();
- return false;
- },
- function(){
- $('.vm_section fieldset').hide();
- $('.vm_section fieldset').first().show(); //Show capacity opts
- return false;
- });
-
- //initialise all sections
- capacity_setup();
- os_boot_setup();
- disks_setup();
- networks_setup();
- inputs_setup();
- graphics_setup();
- context_setup();
- placement_setup();
- raw_setup();
-
- //Process form
- $('button#create_vm_form_easy').click(function(){
- //validate form
-
- var vm_json = {};
-
- //process capacity options
- var scope = section_capacity;
-
- if (!mandatory_filter(scope)){
- notifyError("There are mandatory fields missing in the capacity section");
- return false;
- };
- addSectionJSON(vm_json,scope);
-
- //process os_boot_opts
- scope= section_os_boot;
- switch (templ_type){
- case "xen":
- boot_method = $('#boot_method option:selected',scope).val();
- if (!boot_method.length){
- notifyError("Xen templates must specify a boot method");
- return false;}
- };
-
- if (!mandatory_filter(scope)){
- notifyError("There are mandatory fields missing in the OS Boot options section");
- return false;
- };
- vm_json["OS"] = {};
- addSectionJSON(vm_json["OS"],scope);
-
- //process disks -> fetch from box
- scope = section_disks;
- vm_json["DISK"] = [];
- addBoxJSON(vm_json["DISK"],scope,'#disks_box');
-
- //process nics -> fetch from box
- scope = section_networks;
- vm_json["NIC"] = [];
- addBoxJSON(vm_json["NIC"],scope,'#nics_box');
-
- //process inputs -> fetch from box
- scope = section_inputs;
- vm_json["INPUT"] = [];
- addBoxJSON(vm_json["INPUT"],scope,'#inputs_box');
-
- //process graphics -> fetch fields with value
- scope = section_graphics;
- vm_json["GRAPHICS"] = {};
- addSectionJSON(vm_json["GRAPHICS"],scope);
-
- //context
- scope = section_context;
- var context = $('#CONTEXT',scope).val();
- vm_json["CONTEXT"] = {};
- $('#context_box option',scope).each(function(){
- name = $(this).attr("name");
- value = $(this).val();
- vm_json["CONTEXT"][name]=value;
- });
-
- //placement -> fetch with value
- scope = section_placement;
- addSectionJSON(vm_json,scope);
-
- //raw -> if value set type to driver and fetch
- scope = section_raw;
- vm_json["RAW"] = {};
- addSectionJSON(vm_json["RAW"],scope);
-
- // remove empty elements
- vm_json = removeEmptyObjects(vm_json);
-
- //wrap it in the "vm" object
- vm_json = {vm: vm_json};
-
+ $('#create_vm_dialog #create_vm_proceed').click(function(){
+ var vm_name = $('#create_vm_form #vm_name').val();
+ var template_id = $('#create_vm_form #template_id').val();
+ var vm_json = { vm: { vm_name: vm_name, template_id : template_id }};
Sunstone.runAction("VM.create",vm_json);
-
$('#create_vm_dialog').dialog('close');
- return false;
- });
-
- //Handle manual forms
- $('button#create_vm_form_manual').click(function(){
- var template = $('#textarea_vm_template').val();
-
- //wrap it in the "vm" object
- template = {"vm": {"vm_raw": template}};
-
- Sunstone.runAction("VM.create",template);
- $('#create_vm_dialog').dialog('close');
- return false;
- });
-
- //Reset form - empty boxes
- $('button#reset_vm_form').click(function(){
- $('select#disks_box option',section_disks).remove();
- $('select#nics_box option',section_networks).remove();
- $('select#inputs_box option',section_inputs).remove();
- return true;
- });
-
-
+ return false;
+ });
+
+ $('#create_vm_dialog #create_vm_cancel').click(function(){
+
+ });
}
// Open creation dialog
@@ -1965,5 +794,4 @@ $(document).ready(function(){
initCheckAllBoxes(dataTable_vMachines);
tableCheckboxesListener(dataTable_vMachines);
vMachineInfoListener();
- setupTips($('#create_vm_dialog'));
})
diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js
index 59a2c54434..359f203aec 100644
--- a/src/sunstone/public/js/sunstone-util.js
+++ b/src/sunstone/public/js/sunstone-util.js
@@ -93,6 +93,7 @@ function tableCheckboxesListener(dataTable){
last_action_b.button("disable");
};
$('.create_dialog_button',context).button("enable");
+ $('.alwaysActive',context).button("enable");
//listen to changes in the visible inputs
$('tbody input',dataTable).live("change",function(){
@@ -127,6 +128,7 @@ function tableCheckboxesListener(dataTable){
//any case the create dialog buttons should always be enabled.
$('.create_dialog_button',context).button("enable");
+ $('.alwaysActive',context).button("enable");
});
}
diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js
index dad3ae4cb6..4492c40038 100644
--- a/src/sunstone/public/js/sunstone.js
+++ b/src/sunstone/public/js/sunstone.js
@@ -448,6 +448,10 @@ function insertButtonsInTab(tab_name){
}
+ if (button.alwaysActive) {
+ button_code = $(button_code).addClass("alwaysActive");
+ }
+
$('div#'+tab_name+' .action_blocks').append(button_code);
}//for each button in tab
diff --git a/src/sunstone/templates/index.html b/src/sunstone/templates/index.html
index aa451a553f..e07d76051f 100644
--- a/src/sunstone/templates/index.html
+++ b/src/sunstone/templates/index.html
@@ -25,6 +25,7 @@
+