diff --git a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles.js b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles.js index 6a3a8f45d5..400f0d7481 100644 --- a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles.js +++ b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles.js @@ -22,9 +22,11 @@ define(function(require) { var Locale = require('utils/locale'); var Tips = require('utils/tips'); var OpenNebulaRole = require('opennebula/role'); - var roles_buttons = require('./roles/roles-buttons'); - var roles_vm_buttons = require('./roles/roles-vm-buttons'); + var OpenNebulaVM = require("opennebula/vm"); + var RolesButtons = require('./roles/roles-buttons'); + var RolesVmButtons = require('./roles/roles-vm-buttons'); var StateRolesButtons = require('./roles/state-roles-buttons'); + var StateRolesVmButtons = require('./roles/state-roles-vm-buttons'); var Sunstone = require('sunstone'); var DomDataTable = require('utils/dom-datatable'); var VMRemoteActions = require('utils/remote-actions'); @@ -53,6 +55,8 @@ define(function(require) { var XML_ROOT = "DOCUMENT"; var RESOURCE = "Service"; + var lastRoleIndexSelected = undefined; + /* CONSTRUCTOR */ @@ -153,12 +157,10 @@ define(function(require) { function _setup(context) { var that = this; + var roles = this.roles = that.element.TEMPLATE.BODY.roles; Tips.setup(context); - var lastRoleIndexSelected = undefined - var roles = that.element.TEMPLATE.BODY.roles; - if (roles && roles.length) { that.servicerolesDataTable = new DomDataTable( 'datatable_roles_'+this.panelId, @@ -170,24 +172,27 @@ define(function(require) { customTrListener: function(tableObj, tr){ var rowData = tableObj.dataTable.fnGetData(tr); var roleName = $(rowData[0]).data().name - + var roleIndexSelected = roles.findIndex(function(role) { return role.name === roleName }) - if (lastRoleIndexSelected !== roleIndexSelected) { + var roleSelected = roles[roleIndexSelected]; + var isEqualLastIndex = lastRoleIndexSelected === roleIndexSelected; + + StateRolesButtons.enableStateActions(roleSelected.state); + + if (!isEqualLastIndex) { lastRoleIndexSelected = roleIndexSelected - - var roleSelected = roles[roleIndexSelected]; - - StateRolesButtons.enableStateActions(roleSelected.state); - - $("#roles_extended_info", context).fadeOut('slow', function() { - $(this).html(that.roleHTML(context, roleSelected)) - that.roleSetup($(this), roleSelected) - }).fadeIn('slow'); } + $('#roles_extended_info, context') + .fadeOut(isEqualLastIndex ? 0 : 'slow', function() { + $(this).html(that.roleHTML(context, roleSelected)); + that.roleSetup($(this), roleSelected); + }) + .fadeIn(isEqualLastIndex ? 0 : 'slow'); + // The info listener is triggered instead of // the row selection. So we click the check input to select // the row also @@ -200,12 +205,12 @@ define(function(require) { this.servicerolesDataTable.initialize(); - Sunstone.insertButtonsInTab(TAB_ID, "service_roles_tab", roles_buttons, $('#role_actions', context)); + Sunstone.insertButtonsInTab(TAB_ID, "service_roles_tab", RolesButtons, $('#role_actions', context)); } } - function _roleHTML(context, role) { + function _roleHTML(context, role, callback) { var that = this; var ready_status_gate = that.element.TEMPLATE.BODY.ready_status_gate; var promises = []; @@ -236,7 +241,7 @@ define(function(require) { actions = VMRemoteActions.renderActionsHtml(data); } - roleVms[index] = rowInfoRoleVm(ready, id, name, uname, gname, ips, actions); + roleVms[index] = rowInfoRoleVm(ready, id, name, uname, gname, ips, actions, data.STATE, data.LCM_STATE); } promises.push(OpenNebulaVM.promiseGetVm({ id, success: successCallback })) @@ -249,7 +254,11 @@ define(function(require) { UtilsFoundation.update(context); VMRemoteActions.bindActionsToContext(context) } - + + if (callback && typeof callback === 'function') { + callback(); + } + Tips.setup(context); }); @@ -270,11 +279,17 @@ define(function(require) { }); } - function rowInfoRoleVm(ready, id, name = "", uname = "", gname = "", ips = "", actions = "") { + function rowInfoRoleVm(ready, id, name = "", uname = "", gname = "", ips = "", actions = "", state, lcm_state) { return [ ready, - '', + '', ''+ id +'', name, uname, @@ -285,7 +300,7 @@ define(function(require) { } function _roleSetup(context, role) { - var that = this + var that = this; if(that.servicePanel) { that.serviceroleVMsDataTable = new DomDataTable( @@ -302,15 +317,51 @@ define(function(require) { {"bSortable": false, "aTargets": ["check", 5, 6]} ] } - }); + } + ); + + that.serviceroleVMsDataTable.initialize(); - that.serviceroleVMsDataTable.initialize(); Sunstone.insertButtonsInTab( TAB_ID, "service_roles_tab", - roles_vm_buttons, + RolesVmButtons, $('div#role_vms_actions', context) ); + + $("#role_vms_actionsrefresh_buttons", context).on('click', function(event) { + event.preventDefault(); + + var prevRowsSelected = $(".check_item:checked", that.serviceroleVMsDataTable.dataTable); + var prevIdsSelected = $.map(prevRowsSelected, function(row) { + return $(row).attr('id'); + }); + + var roleSelected = that.roles[lastRoleIndexSelected]; + + that.roleHTML(context, roleSelected, function() { + // for each previous selected vms + $.each(prevIdsSelected, function(_, id) { + // if exists yet, check it + var currentRow = $("input#" + id, that.serviceroleVMsDataTable.dataTable); + currentRow.length && currentRow.trigger("click"); + }); + }); + + event.stopPropagation(); + }); + + $("#" + that.serviceroleVMsDataTable.dataTableId).on("change", "tbody input.check_item", function() { + StateRolesVmButtons.disableAllStateActions(); + + // Enable actions available to any of the selected VMs + var nodes = $("tr", that.serviceroleVMsDataTable.dataTable); //visible nodes only + $.each($("input.check_item:checked", nodes), function() { + StateRolesVmButtons.enableStateActions($(this).attr("state"), $(this).attr("lcm_state")); + }); + + return true; + }); } } }); diff --git a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles/roles-vm-buttons.js b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles/roles-vm-buttons.js index b0be3d2f3b..997492b6d9 100644 --- a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles/roles-vm-buttons.js +++ b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles/roles-vm-buttons.js @@ -15,24 +15,24 @@ /* -------------------------------------------------------------------------- */ define(function(require) { - var Locale = require('utils/locale'); var VMButtons = require('tabs/vms-tab/buttons'); var Buttons = { "RoleVM.hold" : VMButtons["VM.hold"], + "RoleVM.poweroff_hard" : VMButtons["VM.poweroff_hard"], + "RoleVM.poweroff" : VMButtons["VM.poweroff"], + "RoleVM.reboot_hard" : VMButtons["VM.reboot_hard"], + "RoleVM.reboot" : VMButtons["VM.reboot"], + "RoleVM.refresh" : VMButtons["VM.refresh"], "RoleVM.release" : VMButtons["VM.release"], - "RoleVM.suspend" : VMButtons["VM.suspend"], + "RoleVM.resched" : VMButtons["VM.resched"], "RoleVM.resume" : VMButtons["VM.resume"], "RoleVM.stop" : VMButtons["VM.stop"], - "RoleVM.reboot" : VMButtons["VM.reboot"], - "RoleVM.reboot_hard" : VMButtons["VM.reboot_hard"], - "RoleVM.poweroff" : VMButtons["VM.poweroff"], - "RoleVM.poweroff_hard" : VMButtons["VM.poweroff_hard"], - "RoleVM.undeploy" : VMButtons["VM.undeploy"], - "RoleVM.undeploy_hard" : VMButtons["VM.undeploy_hard"], - "RoleVM.terminate" : VMButtons["VM.terminate"], + "RoleVM.suspend" : VMButtons["VM.suspend"], "RoleVM.terminate_hard" : VMButtons["VM.terminate_hard"], - "RoleVM.resched" : VMButtons["VM.resched"], + "RoleVM.terminate" : VMButtons["VM.terminate"], + "RoleVM.undeploy_hard" : VMButtons["VM.undeploy_hard"], + "RoleVM.undeploy" : VMButtons["VM.undeploy"], "RoleVM.unresched" : VMButtons["VM.unresched"] }; diff --git a/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles/state-roles-vm-buttons.js b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles/state-roles-vm-buttons.js new file mode 100644 index 0000000000..8840027614 --- /dev/null +++ b/src/sunstone/public/app/tabs/oneflow-services-tab/panels/roles/state-roles-vm-buttons.js @@ -0,0 +1,241 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +define(function(require) { + var OpenNebulaVM = require('opennebula/vm'); + var Buttons = require('./roles-vm-buttons'); + + var ALL_ACTION_BUTTONS = $.map(Buttons, function(_, action) { + return [action] + }); + + var STATE_ACTIONS = {}; + + STATE_ACTIONS[OpenNebulaVM.STATES.INIT] = ["RoleVM.terminate_hard"]; + + STATE_ACTIONS[OpenNebulaVM.STATES.PENDING] = ["RoleVM.hold", "RoleVM.terminate_hard", ]; + + STATE_ACTIONS[OpenNebulaVM.STATES.HOLD] = ["RoleVM.release", "RoleVM.terminate_hard", ]; + + STATE_ACTIONS[OpenNebulaVM.STATES.ACTIVE] = []; + + STATE_ACTIONS[OpenNebulaVM.STATES.STOPPED] = ["RoleVM.resume", "RoleVM.terminate_hard"]; + + STATE_ACTIONS[OpenNebulaVM.STATES.SUSPENDED] = ["RoleVM.resume", "RoleVM.stop", "RoleVM.terminate_hard"]; + + STATE_ACTIONS[OpenNebulaVM.STATES.DONE] = []; + + STATE_ACTIONS[OpenNebulaVM.STATES.FAILED] = []; + + STATE_ACTIONS[OpenNebulaVM.STATES.POWEROFF] = + ["RoleVM.resched", "RoleVM.resume", "RoleVM.undeploy", "RoleVM.undeploy_hard", "RoleVM.terminate_hard"]; + + STATE_ACTIONS[OpenNebulaVM.STATES.UNDEPLOYED] = ["RoleVM.resume", "RoleVM.terminate_hard"]; + + STATE_ACTIONS[OpenNebulaVM.STATES.CLONING] = ["RoleVM.terminate_hard"]; + + STATE_ACTIONS[OpenNebulaVM.STATES.CLONING_FAILURE] = ["RoleVM.terminate_hard"]; + + + var LCM_STATE_ACTIONS = {}; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.LCM_INIT] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.RUNNING ] = + ["RoleVM.poweroff_hard", "RoleVM.poweroff", "RoleVM.reboot_hard", "RoleVM.reboot", "RoleVM.resched", "RoleVM.stop", "RoleVM.suspend", "RoleVM.terminate_hard", "RoleVM.terminate", "RoleVM.undeploy_hard", "RoleVM.undeploy", "RoleVM.unresched"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.MIGRATE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.SAVE_STOP] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.SAVE_SUSPEND] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.SAVE_MIGRATE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_RESUME] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.EPILOG_STOP] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.EPILOG] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.SHUTDOWN] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.CANCEL] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.CLEANUP_RESUBMIT] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.UNKNOWN ] = + ["RoleVM.poweroff_hard", "RoleVM.poweroff", "RoleVM.resched", "RoleVM.resume", "RoleVM.terminate_hard", "RoleVM.terminate", "RoleVM.undeploy_hard", "RoleVM.undeploy", "RoleVM.unresched"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.SHUTDOWN_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_UNKNOWN] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_SUSPENDED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_STOPPED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.CLEANUP_DELETE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_SNAPSHOT] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_NIC] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_NIC_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_SUSPENDED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.SHUTDOWN_UNDEPLOY] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.EPILOG_UNDEPLOY] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_UNDEPLOY] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_UNDEPLOY] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_PROLOG_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_EPILOG_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_MIGRATE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_MIGRATE_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.EPILOG_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.EPILOG_STOP_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.EPILOG_UNDEPLOY_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_POWEROFF_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_SUSPEND] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_SUSPEND_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_UNDEPLOY_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.BOOT_STOPPED_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_RESUME_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_UNDEPLOY_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_REVERT_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_DELETE_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_SUSPENDED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_REVERT_SUSPENDED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_DELETE_SUSPENDED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_REVERT] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_DELETE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_UNKNOWN] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_UNKNOWN_FAILURE] = ["RoleVM.terminate"]; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_RESIZE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_RESIZE_POWEROFF] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.DISK_RESIZE_UNDEPLOYED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_RESIZE] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_UNDEPLOYED] = []; + + LCM_STATE_ACTIONS[OpenNebulaVM.LCM_STATES.HOTPLUG_SAVEAS_STOPPED] = []; + + + return { + 'disableAllStateActions': disableAllStateActions, + 'disableStateButton': disableStateButton, + 'enableStateButton': enableStateButton, + 'enableStateActions': enableStateActions + }; + + function disableStateButton(action) { + $(".state-dependent[href='" + action + "']", $('#role_vms_actions')) + .prop("disabled", true) + .removeClass("action-enabled") + .addClass("action-disabled") + .on("click.stateaction", function() { return false; }); + } + + function enableStateButton(action) { + $(".state-dependent[href='" + action + "']", $('#role_vms_actions')) + .removeAttr("disabled") + .addClass("action-enabled") + .removeClass("action-disabled") + .off("click.stateaction") + } + + function enableStateActions(state, lcm_state) { + state = parseInt(state); + lcm_state = parseInt(lcm_state); + + var isActiveState = state === OpenNebulaVM.STATES.ACTIVE + + var actionsAvailable = isActiveState + ? LCM_STATE_ACTIONS[lcm_state] + : STATE_ACTIONS[state]; + + if (actionsAvailable === undefined) return; + + $.each(actionsAvailable, function(_, action) { + enableStateButton(action); + }); + } + + function disableAllStateActions() { + $.each(ALL_ACTION_BUTTONS, function(_, action) { + disableStateButton(action); + }); + } +}); diff --git a/src/sunstone/public/app/utils/dom-datatable.js b/src/sunstone/public/app/utils/dom-datatable.js index fc1155efe7..fbde418898 100644 --- a/src/sunstone/public/app/utils/dom-datatable.js +++ b/src/sunstone/public/app/utils/dom-datatable.js @@ -20,8 +20,6 @@ define(function(require) { */ var TabDataTable = require('utils/tab-datatable'); - var SunstoneConfig = require('sunstone-config'); - var Locale = require('utils/locale'); /* CONSTRUCTOR