diff --git a/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb b/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb index 23801b915b..7ce484f82d 100644 --- a/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb @@ -21,13 +21,13 @@ module OpenNebulaJSON include JSONUtils def create(template_json) - template_hash = parse_json(template_json, 'template') + template_hash = parse_json(template_json, 'vmtemplate') if OpenNebula.is_error?(template_hash) return template_hash end if template_hash['template_raw'] - template = vm_hash['template_raw'] + template = template_hash['template_raw'] else template = template_to_str(template_hash) 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/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index d666c3f95e..cb558aa5c7 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -36,7 +36,459 @@ var templates_tab_content = \ '; -var create_template_tmpl = ""; +var create_template_tmpl = '
\ + \ +
\ +
\ +
\ + \ +

Fields marked with are mandatory
\ + Fold / Unfold all sections

\ +
\ +\ + \ +
\ +
\ +

Capacity options

\ +
\ +
Capacity\ +
\ + \ + \ +
Name that the VM will get for description purposes. If NAME is not supplied a name generated by one will be in the form of one-<VID>.
\ +
\ +
\ + \ + \ +
Amount of RAM required for the VM, in Megabytes.
\ +
\ +
\ + \ + \ +
Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.
\ +
\ +
\ + \ + \ +
Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.
\ +
\ +
\ +
\ + \ +
\ +
\ +

Boot/OS options

\ +
\ +
OS and Boot options\ +
\ + \ + \ +
CPU architecture to virtualization
\ +
\ + \ +
\ + \ + \ +
Select boot method
\ +
\ +
\ + \ + \ +
Path to the OS kernel to boot the image
\ +
\ +
\ + \ + \ +
Path to the initrd image
\ +
\ +
\ + \ + \ +
Device to be mounted as root
\ +
\ +
\ + \ + \ +
Arguments for the booting kernel
\ +
\ +
\ + \ + \ +
Path to the bootloader executable
\ +
\ +
\ + \ + \ +
Boot device type
\ +
\ +
\ +
\ +\ +\ + \ +
\ +
\ +

Add disks/images

\ +
\ +
Disks\ +
\ + \ + Disk\ + \ + Image\ + \ +
\ +
\ +
\ + \ + \ +
Name of the image to use
\ +
\ +
\ + \ + \ +
Type of disk device to emulate: ide, scsi
\ +
\ +
\ + \ + \ +
Device to map image disk. If set, it will overwrite the default device mapping
\ +
\ +
\ + \ + \ +
Specific image mapping driver. KVM: raw, qcow2. Xen:tap:aio:, file:. VMware unsupported
\ +
\ +
\ + \ + \ +
Disk type
\ +
\ +
\ + \ + \ +
Disk file location path or URL
\ +
\ +
\ + \ + \ + \ +
Disk file location path or URL. Mandatory for swap, fs and block images
\ +
\ +
\ + \ + \ + \ +
Filesystem type for the fs images
\ +
\ +
\ + \ + \ +
Clone this image
\ +
\ +
\ + \ + \ +
Save this image after shutting down the VM
\ +
\ +
\ + \ + \ +
Mount image as read-only
\ +
\ +
\ + \ + \ +
\ + \ + \ +
\ +
\ +
\ +
\ +\ + \ +
\ +
\ +

Setup Networks

\ +
\ +
Network\ +
\ + \ + Predefined\ + \ + Manual\ + \ + \ +
\ +
\ +
\ + \ + \ +
Name of the network to attach this device
\ +
\ +
\ + \ + \ +
Request an specific IP from the Network
\ +
\ +
\ + \ + \ +
HW address associated with the network interface
\ +
\ +
\ + \ + \ +
Name of the bridge the network device is going to be attached to
\ +
\ +
\ + \ + \ +
Name for the tun device created for the VM
\ +
\ +
\ + \ + \ +
Name of a shell script to be executed after creating the tun device for the VM
\ +
\ +
\ + \ + \ +
Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.
\ +
\ +
\ + \ + \ +
\ + \ + \ +
\ +
\ +
\ +\ +\ + \ +
\ +
\ +

Add inputs

\ +
\ +
Inputs\ +
\ + \ + \ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ + \ + \ +
\ + \ + \ +
\ +
\ +
\ +\ +\ + \ +
\ +
\ +

Add Graphics

\ +
\ +
Graphics\ +
\ + \ + \ +
\ +
\ +
\ + \ + \ +
IP to listen on
\ +
\ +
\ + \ + \ +
Port for the VNC server
\ +
\ +
\ + \ + \ +
Password for the VNC server
\ +
\ +
\ + \ + \ +
Keyboard configuration locale to use in the VNC display
\ +
\ +
\ +
\ +\ +\ + \ +
\ +
\ +

Add context variables

\ +
\ +
Context\ +
\ + \ + \ +
Name for the context variable
\ +
\ +
\ + \ + \ +
Value of the context variable
\ +
\ +
\ + \ + \ +
\ + \ + \ +
\ +
\ +
\ +\ +\ + \ +
\ +
\ +

Add placement options

\ +
\ +
Placement\ +
\ + \ + \ +
Boolean expression that rules out provisioning hosts from list of machines suitable to run this VM
\ +
\ +
\ + \ + \ +
This field sets which attribute will be used to sort the suitable hosts for this VM. Basically, it defines which hosts are more suitable than others
\ +
\ +
\ +
\ +\ +\ + \ +
\ +
\ +

Add Hypervisor raw options

\ +
\ +
Raw\ + \ +
\ + \ + \ + \ +
Raw data to be passed directly to the hypervisor
\ +
\ +
\ +
\ +\ +\ + \ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ +

Write the Virtual Machine template here

\ +
\ + \ +
\ +
\ +
\ +
\ + \ + \ +
\ +
\ +
\ +
\ +
'; var templates_select = ""; var template_list_json = {}; @@ -287,7 +739,7 @@ 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 @@ -447,7 +899,770 @@ function updateTemplateInfo(request,template){ // 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; + }); + + } 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 = -'
\ - \ -
\ -
\ -
\ - \ -

Fields marked with are mandatory
\ - Fold / Unfold all sections

\ -
\ -\ - \ -
\ -
\ -

Capacity options

\ -
\ -
Capacity\ -
\ - \ - \ -
Name that the VM will get for description purposes. If NAME is not supplied a name generated by one will be in the form of one-<VID>.
\ -
\ -
\ - \ - \ -
Amount of RAM required for the VM, in Megabytes.
\ -
\ -
\ - \ - \ -
Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.
\ -
\ -
\ - \ - \ -
Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.
\ -
\ -
\ -
\ - \ -
\ -
\ -

Boot/OS options

\ -
\ -
OS and Boot options\ -
\ - \ - \ -
CPU architecture to virtualization
\ -
\ - \ -
\ - \ - \ -
Select boot method
\ -
\ -
\ - \ - \ -
Path to the OS kernel to boot the image
\ -
\ -
\ - \ - \ -
Path to the initrd image
\ -
\ -
\ - \ - \ -
Device to be mounted as root
\ -
\ -
\ - \ - \ -
Arguments for the booting kernel
\ -
\ -
\ - \ - \ -
Path to the bootloader executable
\ -
\ -
\ - \ - \ -
Boot device type
\ -
\ -
\ -
\ -\ -\ - \ -
\ -
\ -

Add disks/images

\ -
\ -
Disks\ -
\ - \ - Disk\ - \ - Image\ - \ -
\ -
\ -
\ - \ - \ -
Name of the image to use
\ -
\ -
\ - \ - \ -
Type of disk device to emulate: ide, scsi
\ -
\ -
\ - \ - \ -
Device to map image disk. If set, it will overwrite the default device mapping
\ -
\ -
\ - \ - \ -
Specific image mapping driver. KVM: raw, qcow2. Xen:tap:aio:, file:. VMware unsupported
\ -
\ -
\ - \ - \ -
Disk type
\ -
\ -
\ - \ - \ -
Disk file location path or URL
\ -
\ -
\ - \ - \ - \ -
Disk file location path or URL. Mandatory for swap, fs and block images
\ -
\ -
\ - \ - \ - \ -
Filesystem type for the fs images
\ -
\ -
\ - \ - \ -
Clone this image
\ -
\ -
\ - \ - \ -
Save this image after shutting down the VM
\ -
\ -
\ - \ - \ -
Mount image as read-only
\ -
\ -
\ - \ - \ -
\ - \ - \ -
\ -
\ -
\ -
\ -\ - \ -
\ -
\ -

Setup Networks

\ -
\ -
Network\ -
\ - \ - Predefined\ - \ - Manual\ - \ - \ -
\ -
\ -
\ - \ - \ -
Name of the network to attach this device
\ -
\ -
\ - \ - \ -
Request an specific IP from the Network
\ -
\ -
\ - \ - \ -
HW address associated with the network interface
\ -
\ -
\ - \ - \ -
Name of the bridge the network device is going to be attached to
\ -
\ -
\ - \ - \ -
Name for the tun device created for the VM
\ -
\ -
\ - \ - \ -
Name of a shell script to be executed after creating the tun device for the VM
\ -
\ -
\ - \ - \ -
Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.
\ -
\ -
\ - \ - \ -
\ - \ - \ -
\ -
\ -
\ -\ -\ - \ -
\ -
\ -

Add inputs

\ -
\ -
Inputs\ -
\ - \ - \ -
\ -
\ -
\ - \ - \ -
\ -
\ -
\ - \ - \ -
\ - \ - \ -
\ -
\ -
\ -\ -\ - \ -
\ -
\ -

Add Graphics

\ -
\ -
Graphics\ -
\ - \ - \ -
\ -
\ -
\ - \ - \ -
IP to listen on
\ -
\ -
\ - \ - \ -
Port for the VNC server
\ -
\ -
\ - \ - \ -
Password for the VNC server
\ -
\ -
\ - \ - \ -
Keyboard configuration locale to use in the VNC display
\ -
\ -
\ -
\ -\ -\ - \ -
\ -
\ -

Add context variables

\ -
\ -
Context\ -
\ - \ - \ -
Name for the context variable
\ -
\ -
\ - \ - \ -
Value of the context variable
\ -
\ -
\ - \ - \ -
\ - \ - \ -
\ -
\ -
\ -\ -\ - \ -
\ -
\ -

Add placement options

\ -
\ -
Placement\ -
\ - \ - \ -
Boolean expression that rules out provisioning hosts from list of machines suitable to run this VM
\ -
\ -
\ - \ - \ -
This field sets which attribute will be used to sort the suitable hosts for this VM. Basically, it defines which hosts are more suitable than others
\ -
\ -
\ -
\ -\ -\ - \ -
\ -
\ -

Add Hypervisor raw options

\ -
\ -
Raw\ - \ -
\ - \ - \ - \ -
Raw data to be passed directly to the hypervisor
\ -
\ -
\ -
\ -\ -\ - \ -
\ -
\ - \ - \ -
\ -
\ -
\ -
\ -
\ -
\ -

Write the Virtual Machine template here

\ -
\ - \ -
\ -
\ -
\ -
\ - \ - \ -
\ -
\ -
\ +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 ca0864e08f..e07d76051f 100644 --- a/src/sunstone/templates/index.html +++ b/src/sunstone/templates/index.html @@ -25,10 +25,10 @@ + -