diff options
author | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2019-07-18 15:36:39 -0500 |
---|---|---|
committer | Gunnar Mills <gmills@us.ibm.com> | 2019-07-29 16:28:38 +0000 |
commit | 5ff98780e0a9c3987447a83782f1409dd3d11f02 (patch) | |
tree | d916710f88a45e054a1374f0f14336a83feb23d6 /app/server-control | |
parent | ae0353989abe7d9194dba47ca26d803fe11f46b6 (diff) | |
download | phosphor-webui-5ff98780e0a9c3987447a83782f1409dd3d11f02.tar.gz phosphor-webui-5ff98780e0a9c3987447a83782f1409dd3d11f02.zip |
Refactor power operations
Refactored power operations to use checkHostStatus function
that checks host_status property provided by dataService,
instead of polling for host/chassis status.
Added property to check when a power operation is in progress.
This property will show/hide the in progress message and make
other operations unavailable until the operation completes.
We were previously checking whether the server_state property
was set to 'Unreachable', which enables the Power on button in
the middle of a reboot, since the server_state changes to 'Off'
during reboot.
- Removed unused $timeout service
Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: I234749a9a875c7370b52bd23ed74d6e9617cf5e2
Diffstat (limited to 'app/server-control')
-rw-r--r-- | app/server-control/controllers/power-operations-controller.html | 68 | ||||
-rw-r--r-- | app/server-control/controllers/power-operations-controller.js | 233 |
2 files changed, 154 insertions, 147 deletions
diff --git a/app/server-control/controllers/power-operations-controller.html b/app/server-control/controllers/power-operations-controller.html index 2fcb95b..ddf8bda 100644 --- a/app/server-control/controllers/power-operations-controller.html +++ b/app/server-control/controllers/power-operations-controller.html @@ -17,38 +17,42 @@ <div class="row column"> <h3 class="subhead">Select a power operation</h3> </div> - <span class="inactive-message" ng-show="dataService.server_state == 'Unreachable'">There are no power operations to display while a power operation is in progress. When complete, any new power operations will be displayed here.</span> - <!-- Power on displays only when server is shutdown --> - <div class="row column power-option" ng-hide="dataService.server_state == 'Running' || dataService.server_state == 'Quiesced' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || confirm || dataService.loading, transitionAll: confirm}"> - <button id="power__power-on" class="btn btn-secondary" ng-click="powerOn()" role="button" ng-disabled="dataService.server_unreachable"> - <icon file="icon-power.svg"></icon>Power on - </button> - <p class="inline">Attempts to power on the server</p> - </div> - <!-- Power reboot/shutdown options : when server is off all of these are hidden. When one option is selected, the others are disabled. --> - <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmWarmReboot) || dataService.loading, transitionAll: confirm && confirmWarmReboot}"> - <button id="power__warm-boot" class="btn btn-secondary" ng-click="warmRebootConfirm()" role="button" ng-disabled="dataService.server_unreachable"> - <icon file="icon-restart.svg"></icon>Warm reboot</button> - <p class="inline">Attempts to perform an orderly shutdown before restarting the server</p> - <confirm title="warm reboot" confirm="confirmWarmReboot" ng-show="confirmWarmReboot" callback="warmReboot"></confirm> - </div> - <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmColdReboot) || dataService.loading, transitionAll: confirm && confirmColdReboot}"> - <button id="power__cold-boot" class="btn btn-secondary" ng-click="coldRebootConfirm()" role="button" ng-disabled="dataService.server_unreachable"> - <icon file="icon-restart.svg"></icon>Cold reboot</button> - <p class="inline">Shuts down the server immediately, then restarts it</p> - <confirm title="cold reboot" confirm="confirmColdReboot" ng-show="confirmColdReboot" cancel="coldbootCancel" callback="coldReboot"></confirm> - </div> - <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmOrderlyShutdown) || dataService.loading, transitionAll: confirm && confirmOrderlyShutdown}"> - <button id="power__soft-shutdown" class="btn btn-secondary" ng-click="orderlyShutdownConfirm()" role="button" ng-disabled="dataService.server_unreachable"> - <icon file="icon-power.svg"></icon>Orderly shutdown</button> - <p class="inline">Attempts to stop all software on the server before removing power</p> - <confirm title="orderly shutdown" confirm="confirmOrderlyShutdown" ng-show="confirmOrderlyShutdown" cancel="orderlyShutdownCancel" callback="orderlyShutdown"></confirm> - </div> - <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmImmediateShutdown) || dataService.loading, transitionAll: confirm && confirmImmediateShutdown}"> - <button id="power__hard-shutdown" class="btn btn-secondary" ng-click="immediateShutdownConfirm()" role="button" ng-disabled="dataService.server_unreachable"> - <icon file="icon-power.svg"></icon>Immediate shutdown</button> - <p class="inline">Removes power from the server without waiting for software to stop</p> - <confirm title="immediate shutdown" confirm="confirmImmediateShutdown" ng-show="confirmImmediateShutdown" cancel="immediatelyShutdownCancel" callback="immediateShutdown"></confirm> + <div ng-if="operationPending"> + <span class="inactive-message">There are no power operations to display while a power operation is in progress. When complete, any new power operations will be displayed here.</span> + </div> + <div ng-if="!operationPending"> + <!-- Power on displays only when server is shutdown --> + <div class="row column power-option" ng-hide="dataService.server_state == 'Running' || dataService.server_state == 'Quiesced' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || confirm || dataService.loading, transitionAll: confirm}"> + <button id="power__power-on" class="btn btn-secondary" ng-click="powerOn()" role="button" ng-disabled="dataService.server_unreachable"> + <icon file="icon-power.svg"></icon>Power on + </button> + <p class="inline">Attempts to power on the server</p> + </div> + <!-- Power reboot/shutdown options : when server is off all of these are hidden. When one option is selected, the others are disabled. --> + <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmWarmReboot) || dataService.loading, transitionAll: confirm && confirmWarmReboot}"> + <button id="power__warm-boot" class="btn btn-secondary" ng-click="warmRebootConfirm()" role="button" ng-disabled="dataService.server_unreachable"> + <icon file="icon-restart.svg"></icon>Warm reboot</button> + <p class="inline">Attempts to perform an orderly shutdown before restarting the server</p> + <confirm title="warm reboot" confirm="confirmWarmReboot" ng-show="confirmWarmReboot" callback="warmReboot"></confirm> + </div> + <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmColdReboot) || dataService.loading, transitionAll: confirm && confirmColdReboot}"> + <button id="power__cold-boot" class="btn btn-secondary" ng-click="coldRebootConfirm()" role="button" ng-disabled="dataService.server_unreachable"> + <icon file="icon-restart.svg"></icon>Cold reboot</button> + <p class="inline">Shuts down the server immediately, then restarts it</p> + <confirm title="cold reboot" confirm="confirmColdReboot" ng-show="confirmColdReboot" cancel="coldbootCancel" callback="coldReboot"></confirm> + </div> + <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmOrderlyShutdown) || dataService.loading, transitionAll: confirm && confirmOrderlyShutdown}"> + <button id="power__soft-shutdown" class="btn btn-secondary" ng-click="orderlyShutdownConfirm()" role="button" ng-disabled="dataService.server_unreachable"> + <icon file="icon-power.svg"></icon>Orderly shutdown</button> + <p class="inline">Attempts to stop all software on the server before removing power</p> + <confirm title="orderly shutdown" confirm="confirmOrderlyShutdown" ng-show="confirmOrderlyShutdown" cancel="orderlyShutdownCancel" callback="orderlyShutdown"></confirm> + </div> + <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmImmediateShutdown) || dataService.loading, transitionAll: confirm && confirmImmediateShutdown}"> + <button id="power__hard-shutdown" class="btn btn-secondary" ng-click="immediateShutdownConfirm()" role="button" ng-disabled="dataService.server_unreachable"> + <icon file="icon-power.svg"></icon>Immediate shutdown</button> + <p class="inline">Removes power from the server without waiting for software to stop</p> + <confirm title="immediate shutdown" confirm="confirmImmediateShutdown" ng-show="confirmImmediateShutdown" cancel="immediatelyShutdownCancel" callback="immediateShutdown"></confirm> + </div> </div> </div> </div> diff --git a/app/server-control/controllers/power-operations-controller.js b/app/server-control/controllers/power-operations-controller.js index 9713d21..986ac3b 100644 --- a/app/server-control/controllers/power-operations-controller.js +++ b/app/server-control/controllers/power-operations-controller.js @@ -10,11 +10,10 @@ window.angular && (function(angular) { 'use strict'; angular.module('app.serverControl').controller('powerOperationsController', [ - '$scope', 'APIUtils', 'dataService', 'Constants', '$timeout', '$interval', - '$q', 'toastService', + '$scope', 'APIUtils', 'dataService', 'Constants', '$interval', '$q', + 'toastService', function( - $scope, APIUtils, dataService, Constants, $timeout, $interval, $q, - toastService) { + $scope, APIUtils, dataService, Constants, $interval, $q, toastService) { $scope.dataService = dataService; // Is a || of the other 4 "confirm" variables to ensure only // one confirm is shown at a time. @@ -25,35 +24,39 @@ window.angular && (function(angular) { $scope.confirmImmediateShutdown = false; $scope.loading = true; - var pollChassisStatusTimer = undefined; - var pollStartTime = null; + // When a power operation is in progress, set to true, + // when a power operation completes (success/fail) set to false. + // This property is used to show/hide the 'in progress' message + // in markup. + $scope.operationPending = false; /** * Checks the host status provided by the dataService using an * interval timer * @param {string} statusType : host status type to check for - * @param {number} timeout : timeout limit - * @param {string} error : error message + * @param {number} timeout : timeout limit, defaults to 5 minutes + * @param {string} error : error message, defaults to 'Time out' * @returns {Promise} : returns a deferred promise that will be fulfilled * if the status is met or be rejected if the timeout is reached */ - var checkHostStatus = (statusType, timeout, error = 'Time out.') => { - const deferred = $q.defer(); - const start = new Date(); - const checkHostStatusInverval = $interval(() => { - let now = new Date(); - let timePassed = now.getTime() - start.getTime(); - if (timePassed > timeout) { - deferred.reject(error); - $interval.cancel(checkHostStatusInverval); - } - if (dataService.server_state === statusType) { - deferred.resolve(); - $interval.cancel(checkHostStatusInverval); - } - }, Constants.POLL_INTERVALS.POWER_OP); - return deferred.promise; - }; + var checkHostStatus = + (statusType, timeout = 300000, error = 'Time out.') => { + const deferred = $q.defer(); + const start = new Date(); + const checkHostStatusInverval = $interval(() => { + let now = new Date(); + let timePassed = now.getTime() - start.getTime(); + if (timePassed > timeout) { + deferred.reject(error); + $interval.cancel(checkHostStatusInverval); + } + if (dataService.server_state === statusType) { + deferred.resolve(); + $interval.cancel(checkHostStatusInverval); + } + }, Constants.POLL_INTERVALS.POWER_OP); + return deferred.promise; + }; APIUtils.getLastPowerTime() .then( @@ -76,71 +79,56 @@ window.angular && (function(angular) { (dataService.server_state == 'Running') ? 'Off' : 'Running'; }; - $scope.powerOn = function() { - $scope.loading = true; + /** + * Initiate Power on + */ + $scope.powerOn = () => { + $scope.operationPending = true; dataService.setUnreachableState(); APIUtils.hostPowerOn() - .then(function(response) { - return response; + .then(() => { + // Check for on state + return checkHostStatus( + Constants.HOST_STATE_TEXT.on, Constants.TIMEOUT.HOST_ON, + Constants.MESSAGES.POLL.HOST_ON_TIMEOUT); }) - .then(function(lastStatus) { - return APIUtils.pollHostStatusTillOn(); + .catch((error) => { + console.log(error); + toastService.error(Constants.MESSAGES.POWER_OP.POWER_ON_FAILED); }) - .then(function(hostState) { - $scope.loading = false; + .finally(() => { + $scope.operationPending = false; }) - .catch(function(error) { - toastService.error(Constants.MESSAGES.POWER_OP.POWER_ON_FAILED); - $scope.loading = false; - }); }; - function pollChassisStatusTillOff() { - var deferred = $q.defer(); - pollChassisStatusTimer = $interval(function() { - var now = new Date(); - if ((now.getTime() - pollStartTime.getTime()) >= - Constants.TIMEOUT.CHASSIS_OFF) { - $interval.cancel(pollChassisStatusTimer); - pollChassisStatusTimer = undefined; - deferred.reject( - new Error(Constants.MESSAGES.POLL.CHASSIS_OFF_TIMEOUT)); - } - APIUtils.getChassisState() - .then(function(state) { - if (state === Constants.CHASSIS_POWER_STATE.off_code) { - $interval.cancel(pollChassisStatusTimer); - pollChassisStatusTimer = undefined; - deferred.resolve(state); - } - }) - .catch(function(error) { - $interval.cancel(pollChassisStatusTimer); - pollChassisStatusTimer = undefined; - deferred.reject(error); - }); - }, Constants.POLL_INTERVALS.POWER_OP); - - return deferred.promise; - } - $scope.warmReboot = function() { - $scope.loading = true; + /** + * Initiate Orderly reboot + * Attempts to stop all software + */ + $scope.warmReboot = () => { + $scope.operationPending = true; dataService.setUnreachableState(); APIUtils.hostReboot() - .then(function(response) { - return response; - }) - .then(function(lastStatus) { - return APIUtils.pollHostStatusTilReboot(); + .then(() => { + // Check for off state + return checkHostStatus( + Constants.HOST_STATE_TEXT.off, Constants.TIMEOUT.HOST_OFF, + Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT); }) - .then(function(hostState) { - $scope.loading = false; + .then(() => { + // Check for on state + return checkHostStatus( + Constants.HOST_STATE_TEXT.on, Constants.TIMEOUT.HOST_ON, + Constants.MESSAGES.POLL.HOST_ON_TIMEOUT); }) - .catch(function(error) { + .catch((error) => { + console.log(error); toastService.error( Constants.MESSAGES.POWER_OP.WARM_REBOOT_FAILED); - $scope.loading = false; - }); + }) + .finally(() => { + $scope.operationPending = false; + }) }; $scope.warmRebootConfirm = function() { @@ -152,33 +140,40 @@ window.angular && (function(angular) { $scope.confirmWarmReboot = true; }; - $scope.coldReboot = function() { - $scope.loading = true; + /** + * Initiate Immediate reboot + * Does not attempt to stop all software + */ + $scope.coldReboot = () => { + $scope.operationPending = true; dataService.setUnreachableState(); APIUtils.chassisPowerOff() - .then(function() { + .then(() => { + // Check for off state return checkHostStatus( Constants.HOST_STATE_TEXT.off, Constants.TIMEOUT.HOST_OFF_IMMEDIATE, Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT); }) - .then(function() { + .then(() => { return APIUtils.hostPowerOn(); }) - .then(function() { + .then(() => { + // Check for on state return checkHostStatus( Constants.HOST_STATE_TEXT.on, Constants.TIMEOUT.HOST_ON, Constants.MESSAGES.POLL.HOST_ON_TIMEOUT); }) - .catch(function(error) { + .catch((error) => { console.log(error); toastService.error( Constants.MESSAGES.POWER_OP.COLD_REBOOT_FAILED); }) - .finally(function() { - $scope.loading = false; + .finally(() => { + $scope.operationPending = false; }) }; + $scope.coldRebootConfirm = function() { if ($scope.confirm) { return; @@ -187,29 +182,30 @@ window.angular && (function(angular) { $scope.confirmColdReboot = true; }; - $scope.orderlyShutdown = function() { - $scope.loading = true; + /** + * Initiate Orderly shutdown + * Attempts to stop all software + */ + $scope.orderlyShutdown = () => { + $scope.operationPending = true; dataService.setUnreachableState(); APIUtils.hostPowerOff() - .then(function(response) { - return response; - }) - .then(function(lastStatus) { - return APIUtils.pollHostStatusTillOff(); - }) - .then(function(hostState) { - pollStartTime = new Date(); - return pollChassisStatusTillOff(); - }) - .then(function(chassisState) { - $scope.loading = false; + .then(() => { + // Check for off state + return checkHostStatus( + Constants.HOST_STATE_TEXT.off, Constants.TIMEOUT.HOST_OFF, + Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT); }) - .catch(function(error) { + .catch((error) => { + console.log(error); toastService.error( Constants.MESSAGES.POWER_OP.ORDERLY_SHUTDOWN_FAILED); - $scope.loading = false; - }); + }) + .finally(() => { + $scope.operationPending = false; + }) }; + $scope.orderlyShutdownConfirm = function() { if ($scope.confirm) { return; @@ -218,27 +214,34 @@ window.angular && (function(angular) { $scope.confirmOrderlyShutdown = true; }; - $scope.immediateShutdown = function() { - $scope.loading = true; + /** + * Initiate Immediate shutdown + * Does not attempt to stop all software + */ + $scope.immediateShutdown = () => { + $scope.operationPending = true; dataService.setUnreachableState(); APIUtils.chassisPowerOff() - .then(function(response) { - return response; - }) - .then(function(lastStatus) { - pollStartTime = new Date(); - return pollChassisStatusTillOff(); + .then(() => { + // Check for off state + return checkHostStatus( + Constants.HOST_STATE_TEXT.off, + Constants.TIMEOUT.HOST_OFF_IMMEDIATE, + Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT); }) - .then(function(chassisState) { + .then(() => { dataService.setPowerOffState(); - $scope.loading = false; }) - .catch(function(error) { + .catch((error) => { + console.log(error); toastService.error( Constants.MESSAGES.POWER_OP.IMMEDIATE_SHUTDOWN_FAILED); - $scope.loading = false; - }); + }) + .finally(() => { + $scope.operationPending = false; + }) }; + $scope.immediateShutdownConfirm = function() { if ($scope.confirm) { return; |