diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index 12e20ae57c..69b869a46d 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -99,9 +99,8 @@ module OpenNebulaJSON super(params['hard']) end - def migrate(params=Hash.new, live=false, enforce=false) - # TODO add enforce parameter - super(params['host_id'], live) + def migrate(params=Hash.new, live=false) + super(params['host_id'], live, params['enforce']) end def save_as(params=Hash.new) diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index 24bc67c37c..74c42bf3b7 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -709,12 +709,12 @@ var OpenNebula = { "deploy",action_obj); }, "livemigrate": function(params){ - var action_obj = {"host_id": params.data.extra_param}; + var action_obj = params.data.extra_param; OpenNebula.Action.simple_action(params,OpenNebula.VM.resource, "livemigrate",action_obj); }, "migrate": function(params){ - var action_obj = {"host_id": params.data.extra_param}; + var action_obj = params.data.extra_param; OpenNebula.Action.simple_action(params,OpenNebula.VM.resource, "migrate",action_obj); }, diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js index c1b805f6e4..1d0aa51f8b 100644 --- a/src/sunstone/public/js/plugins/config-tab.js +++ b/src/sunstone/public/js/plugins/config-tab.js @@ -213,6 +213,17 @@ var settings_update_password = '
\
\
\ \ +
\ +
\ + \ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\
\
\ \ @@ -256,12 +267,18 @@ function setupUpdatePassword() { $('#settings_update_password_form',dialog).submit(function(){ var pw=$('#new_password',this).val(); + var confirm_password=$('#confirm_password',this).val(); if (!pw.length){ notifyError(tr("Fill in a new password")); return false; } + if (pw !== confirm_password){ + notifyError(tr("Password does not match")); + return false; + } + Sunstone.runAction("UserSettings.passwd",[-1],pw); $('#settings_update_password',dialogs_context).trigger("reveal:close") return false; @@ -490,7 +507,7 @@ $(document).ready(function(){ success: function(request, group_list) { var group_dropdown_options = ""; $.each(group_list,function(){ - group_dropdown_options += + group_dropdown_options += ''; @@ -504,4 +521,4 @@ $(document).ready(function(){ $config_dialog.reveal(); }); -}); \ No newline at end of file +}); diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 23e263c551..b99ac2f941 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -172,6 +172,17 @@ var update_pw_tmpl = '
\
\
\
\ +
\ +
\ + \ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\
\
\ \ @@ -870,12 +881,18 @@ function setupUpdatePasswordDialog(){ $('#update_user_pw_form',dialog).submit(function(){ var pw=$('#new_password',this).val(); + var confirm_password=$('#confirm_password',this).val(); if (!pw.length){ notifyError(tr("Fill in a new password")); return false; } + if (pw !== confirm_password){ + notifyError(tr("Password does not match")); + return false; + } + Sunstone.runAction("User.passwd",getSelectedNodes(dataTable_users),pw); $update_pw_dialog.trigger("reveal:close") return false; diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 8591237097..734532a3dd 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -389,10 +389,103 @@ var deploy_vm_tmpl ='\ \
'; +var migrate_vm_tmpl ='\ +
\ +

\ + '+tr("Migrate Virtual Machine")+'\ +

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

\ +
\ +
\ + '+tr("Select a Host")+'\ +
\ +
\ + \ +
\ +
\ + \ +
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
' + tr("ID") + '' + tr("Name") + '' + tr("Cluster") + '' + tr("RVMs") + '' + tr("Real CPU") + '' + tr("Allocated CPU") + '' + tr("Real MEM") + '' + tr("Allocated MEM") + '' + tr("Status") + '' + tr("IM MAD") + '' + tr("VM MAD") + '' + tr("Last monitored on") + '
\ + \ +
\ +
\ + '+tr("Please select a Host from the list")+'\ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ +

'+tr("Advanced options")+'

\ +
\ +
\ +
\ +
\ + \ +
\ +
\ + \ +
\ +
' + + tr("If it is set to true, the host capacity will be checked. This will only affect oneadmin requests, regular users resize requests will always be enforced") + + '
\ +
\ +
\ + \ + ×\ + \ +
'; + var vmachine_list_json = {}; var dataTable_vMachines; var $create_vm_dialog; var $deploy_vm_dialog; +var $migrate_vm_dialog; var $vnc_dialog; var rfb; @@ -472,19 +565,31 @@ var vm_actions = { }, "VM.migrate" : { - type: "multiple", + type: "custom", + call: function(){ + popUpMigrateVMDialog(false); + } + }, + + "VM.migrate_action" : { + type: "single", call: OpenNebula.VM.migrate, callback: vmShow, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, error: onError, notify: true }, "VM.migrate_live" : { - type: "multiple", + type: "custom", + call: function(){ + popUpMigrateVMDialog(true); + } + }, + + "VM.migrate_live_action" : { + type: "single", call: OpenNebula.VM.livemigrate, callback: vmShow, - elements: vmElements, error: onError, notify: true }, @@ -953,20 +1058,18 @@ var vm_buttons = { condition: mustBeAdmin }, "VM.migrate" : { - type: "confirm_with_select", + type: "action", text: tr("Migrate"), tip: tr("This will migrate the selected VMs to the chosen host"), layout: "vmsplanification_buttons", - select: hosts_sel, condition: mustBeAdmin }, "VM.migrate_live" : { - type: "confirm_with_select", + type: "action", text: tr("Migrate") + ' live', tip: tr("This will live-migrate the selected VMs to the chosen host"), layout: "vmsplanification_buttons", - select: hosts_sel, condition: mustBeAdmin }, "VM.hold" : { @@ -3354,6 +3457,107 @@ function setupDeployVMDialog(){ }); } +function setupMigrateVMDialog(live){ + dialogs_context.append('
'); + //Insert HTML in place + $migrate_vm_dialog = $('#migrate_vm_dialog') + var dialog = $migrate_vm_dialog; + dialog.html(migrate_vm_tmpl); + dialog.addClass("reveal-modal large max-height"); + + var dataTable_migrate_hosts = $('#migrate_datatable_hosts', dialog).dataTable({ + "iDisplayLength": 4, + "bAutoWidth":false, + "sDom" : '<"H">t<"F"p>', + "aoColumnDefs": [ + { "bSortable": false, "aTargets": ["check",5,6,7,8] }, + { "sWidth": "35px", "aTargets": [0] }, //check, ID, RVMS, Status, + { "bVisible": false, "aTargets": [3,5,7,10,11,12]} + ], + "fnDrawCallback": function(oSettings) { + var nodes = this.fnGetNodes(); + $.each(nodes, function(){ + if ($(this).find("td:eq(0)").html() == $('#HOST_ID', dialog).val()) { + $("td", this).addClass('markrow'); + $('input.check_item', this).attr('checked','checked'); + } + }) + } + }); + + $('tbody input.check_item:checked',dataTable_vMachines).each(function(){ + var data = dataTable_vMachines.fnGetData( $(this).closest('tr')[0] ); + $("#current_hosts_of_vms").append(''+tr("VM")+' ['+$(this).val() + '] ' + tr("is currently running on Host") + ' [' + data[8] + ']
') + }); + + // Retrieve the images to fill the datatable + update_datatable_template_hosts(dataTable_migrate_hosts); + + $('#migrate_hosts_table_search', dialog).keyup(function(){ + dataTable_migrate_hosts.fnFilter( $(this).val() ); + }) + + $('#migrate_datatable_hosts tbody', dialog).delegate("tr", "click", function(e){ + var aData = dataTable_migrate_hosts.fnGetData(this); + + $("td.markrow", dataTable_migrate_hosts).removeClass('markrow'); + $('tbody input.check_item', dataTable_migrate_hosts).removeAttr('checked'); + + $('#host_selected', dialog).show(); + $('#select_host', dialog).hide(); + $('.alert-box', dialog).hide(); + + $("td", this).addClass('markrow'); + $('input.check_item', this).attr('checked','checked'); + + $('#HOST_NAME', dialog).text(aData[2]); + $('#HOST_ID', dialog).val(aData[1]); + return true; + }); + + $("#refresh_migrate_hosts_table_button_class").die(); + $("#refresh_migrate_hosts_table_button_class").live('click', function(){ + update_datatable_template_hosts($('#migrate_datatable_hosts').dataTable()); + }); + + $('#advanced_migrate', dialog).hide(); + $('#advanced_toggle',dialog).click(function(){ + $('#advanced_migrate',dialog).toggle(); + return false; + }); + + setupTips(dialog); + + $('#migrate_vm_form',dialog).submit(function(){ + var extra_info = {}; + + if ($('#HOST_ID', dialog).val()) { + extra_info['host_id'] = $('#HOST_ID', dialog).val(); + } else { + notifyError(tr("You have not selected a host")); + return false; + } + + extra_info['enforce'] = $("#enforce", this).is(":checked") ? true : false + + //notifySubmit("Template.instantiate",template_id, extra_msg); + + $.each(getSelectedNodes(dataTable_vMachines), function(index, elem) { + console.log(elem) + if (live) { + console.log("live") + Sunstone.runAction("VM.migrate_live_action", elem, extra_info); + } else { + console.log("migrate") + Sunstone.runAction("VM.migrate_action", elem, extra_info); + } + }); + + $migrate_vm_dialog.trigger("reveal:close") + return false; + }); +} + // Open creation dialog function popUpDeployVMDialog(){ setupDeployVMDialog(); @@ -3361,6 +3565,11 @@ function popUpDeployVMDialog(){ } +// Open creation dialog +function popUpMigrateVMDialog(live){ + setupMigrateVMDialog(live); + $migrate_vm_dialog.reveal(); +} //Prepares autorefresh diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 5755ed6447..35b0b1d8ab 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -867,70 +867,6 @@ function insertButtonsInTab(tab_name, panel_name, panel_buttons, custom_context) //another containing a list of actions that can be folded/unfolded. function initListButtons(){ - // //for each multi_action select - // $('.multi_action_slct',main_tabs_context).each(function(){ - // //prepare replacement buttons - // var buttonset = $('
'+tr("Previous action")+'')//.button(); - // button1.attr('disabled','disabled'); - // var button2 = $('') - // //.button({ - // // text:false, - // // icons: { primary: "ui-icon-triangle-1-s" } - // //}); - // // buttonset.append(button1); - // // buttonset.append(button2); - // // buttonset.buttonset(); -//// - // //prepare list - // var options = $('option', $(this)); - // var list = $('
    '); - // $.each(options,function(){ - // var classes = $(this).attr('class'); - // var item = $('
  • '); - // var a = $(''+$(this).text()+''); - // a.val($(this).val()); - // item.html(a); - // list.append(item); - // }); - // list.css({ - // "display":"none" - // }); -// - // $(this).before(buttonset); - // $(this).parents('.action_blocks').append(list); - // $(this).remove(); -// - // }); -// - // //below the listeners for events on these buttons and list -// - // //enable run the last action button - // //$('.action_list li a',main_tabs_context).click(function(){ - // // //enable run last action button - // // var prev_action_button = $('.last_action_button',$(this).parents('.action_blocks')); - // // prev_action_button.val($(this).val()); - // // prev_action_button.removeClass("confirm_with_select_button"); - // // prev_action_button.removeClass("confirm_button"); - // // prev_action_button.removeClass("action_button"); - // // prev_action_button.addClass($(this).attr('class')); - // // prev_action_button.button("option","label",$(this).text()); - // // prev_action_button.button("enable"); - // // $(this).parents('ul').hide("blind",100); - // // //return false; - // //}); -// - // //Show the list of actions in place - // $('.list_button',main_tabs_context).click(function(){ - // $('.action_list',$(this).parents('.action_blocks')).css({ - // "left": $(this).prev().position().left, - // "top": $(this).prev().position().top+13, - // "width": $(this).parent().outerWidth()-11 - // }); - // //100ms animation time - // $('.action_list',$(this).parents('.action_blocks')).toggle("blind",100); - // return false; - // }); } //Prepares the standard confirm dialogs @@ -947,6 +883,11 @@ function setupConfirmDialogs(){
    \
    \
    '+tr("You have to confirm this action.")+'
    \ +
    \ +
    \ +
    \ +

    \ +
    \
    \
    '+tr("Do you want to proceed?")+'
    \
    \ @@ -958,27 +899,14 @@ function setupConfirmDialogs(){ ×\
    '); - //prepare the jquery dialog - //dialog.dialog({ - // resizable:false, - // modal:true, - // width:300, - // heigth:200, - // autoOpen:false - //}); dialog.addClass("reveal-modal"); - - //enhace the button look - //$('button',dialog).button(); - - dialogs_context.append('
    '); dialog = $('div#confirm_with_select_dialog',dialogs_context); dialog.html( '
    \

    \ - '+tr("Confirm")+'\ + '+tr("Confirm")+'

    \

    \
    \
    \ @@ -989,6 +917,9 @@ function setupConfirmDialogs(){ \ \ +
    \ +
    \ + \
    \
    \
    \ @@ -998,18 +929,8 @@ function setupConfirmDialogs(){ ×\ '); - //prepare the jquery dialog - //dialog.dialog({ - // resizable:false, - // modal:true, - // width:300, - // heigth:300, - // autoOpen:false - //}); dialog.addClass("reveal-modal") - //$('button',dialog).button(); - //when we proceed with a "confirm with select" we need to //find out if we are running an action with a parametre on a datatable //items or if its just an action @@ -1063,6 +984,11 @@ function popUpConfirmDialog(target_elem){ $('button#confirm_proceed',dialog).val(value); + var action = SunstoneCfg["actions"][value]; + if (action.elements()) { + $("#confirm_action").html(tr("Action: ") + value) + $("#confirm_ids").html(tr("Selected resources: ") + action.elements().join(', ')) + } $('div#confirm_tip',dialog).text(tip); dialog.reveal(); @@ -1087,6 +1013,12 @@ function popUpConfirmWithSelectDialog(target_elem){ $('select#confirm_select',dialog).html(select_var); $('div#confirm_with_select_tip',dialog).text(tip); + var action = SunstoneCfg["actions"][value]; + if (action.elements()) { + $("#confirm_action").html(tr("Action: ") + value) + $("#confirm_ids").html(tr("Selected resources: ") + action.elements().join(', ')) + } + $('button#confirm_with_select_proceed',dialog).val(value); dialog.reveal(); }