xref: /openbmc/phosphor-webui/app/server-control/controllers/power-operations-controller.js (revision 6add8325ebf5c04731aa14ea4233de51fa897ef4)
1/**
2 * Controller for power-operations
3 *
4 * @module app/serverControl
5 * @exports powerOperationsController
6 * @name powerOperationsController
7 */
8
9window.angular && (function(angular) {
10  'use strict';
11
12  angular.module('app.serverControl').controller('powerOperationsController', [
13    '$scope', 'APIUtils', 'dataService', 'Constants', '$timeout', '$interval',
14    '$interpolate', '$q',
15    function(
16        $scope, APIUtils, dataService, Constants, $timeout, $interval,
17        $interpolate, $q) {
18      $scope.dataService = dataService;
19      $scope.confirm = false;
20      $scope.power_confirm = false;
21      $scope.warmboot_confirm = false;
22      $scope.coldboot_confirm = false;
23      $scope.orderly_confirm = false;
24      $scope.immediately_confirm = false;
25      $scope.loading = true;
26
27      var pollChassisStatusTimer = undefined;
28      var pollHostStatusTimer = undefined;
29      var pollStartTime = null;
30
31      //@TODO: call api and get proper state
32
33      APIUtils.getLastPowerTime()
34          .then(
35              function(data) {
36                if (data.data == 0) {
37                  $scope.power_time = 'not available';
38                } else {
39                  $scope.power_time = data.data;
40                }
41              },
42              function(error) {
43                console.log(JSON.stringify(error));
44              })
45          .finally(function() {
46            $scope.loading = false;
47          });
48
49      $scope.toggleState = function() {
50        dataService.server_state =
51            (dataService.server_state == 'Running') ? 'Off' : 'Running';
52      };
53
54      $scope.powerOn = function() {
55        $scope.loading = true;
56        dataService.setUnreachableState();
57        APIUtils.hostPowerOn()
58            .then(function(response) {
59              return response;
60            })
61            .then(function(lastStatus) {
62              pollStartTime = new Date();
63              return pollHostStatusTillOn();
64            })
65            .then(function(hostState) {
66              $scope.loading = false;
67            })
68            .catch(function(error) {
69              dataService.activateErrorModal({
70                title: Constants.MESSAGES.POWER_OP.POWER_ON_FAILED,
71                description: error.statusText ?
72                    $interpolate(
73                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
74                        {status: error.status, description: error.statusText}) :
75                    error
76              });
77              $scope.loading = false;
78            });
79      };
80      $scope.powerOnConfirm = function() {
81        if ($scope.confirm) {
82          return;
83        }
84        $scope.confirm = true;
85        $scope.power_confirm = true;
86      };
87
88      function pollChassisStatusTillOff() {
89        var deferred = $q.defer();
90        pollChassisStatusTimer = $interval(function() {
91          var now = new Date();
92          if ((now.getTime() - pollStartTime.getTime()) >=
93              Constants.TIMEOUT.CHASSIS_OFF) {
94            $interval.cancel(pollChassisStatusTimer);
95            pollChassisStatusTimer = undefined;
96            deferred.reject(
97                new Error(Constants.MESSAGES.POLL.CHASSIS_OFF_TIMEOUT));
98          }
99          APIUtils.getChassisState()
100              .then(function(state) {
101                if (state === Constants.CHASSIS_POWER_STATE.off_code) {
102                  $interval.cancel(pollChassisStatusTimer);
103                  pollChassisStatusTimer = undefined;
104                  deferred.resolve(state);
105                }
106              })
107              .catch(function(error) {
108                $interval.cancel(pollChassisStatusTimer);
109                pollChassisStatusTimer = undefined;
110                deferred.reject(error);
111              });
112        }, Constants.POLL_INTERVALS.POWER_OP);
113
114        return deferred.promise;
115      }
116
117      function pollHostStatusTillOn() {
118        var deferred = $q.defer();
119        pollHostStatusTimer = $interval(function() {
120          var now = new Date();
121          if ((now.getTime() - pollStartTime.getTime()) >=
122              Constants.TIMEOUT.HOST_ON) {
123            $interval.cancel(pollHostStatusTimer);
124            pollHostStatusTimer = undefined;
125            deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_ON_TIMEOUT));
126          }
127          APIUtils.getHostState()
128              .then(function(state) {
129                if (state === Constants.HOST_STATE_TEXT.on_code) {
130                  $interval.cancel(pollHostStatusTimer);
131                  pollHostStatusTimer = undefined;
132                  deferred.resolve(state);
133                } else if (state === Constants.HOST_STATE_TEXT.error_code) {
134                  $interval.cancel(pollHostStatusTimer);
135                  pollHostStatusTimer = undefined;
136                  deferred.reject(
137                      new Error(Constants.MESSAGES.POLL.HOST_QUIESCED));
138                }
139              })
140              .catch(function(error) {
141                $interval.cancel(pollHostStatusTimer);
142                pollHostStatusTimer = undefined;
143                deferred.reject(error);
144              });
145        }, Constants.POLL_INTERVALS.POWER_OP);
146
147        return deferred.promise;
148      }
149
150      function pollHostStatusTillOff() {
151        var deferred = $q.defer();
152        pollHostStatusTimer = $interval(function() {
153          var now = new Date();
154          if ((now.getTime() - pollStartTime.getTime()) >=
155              Constants.TIMEOUT.HOST_OFF) {
156            $interval.cancel(pollHostStatusTimer);
157            pollHostStatusTimer = undefined;
158            deferred.reject(
159                new Error(Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT));
160          }
161          APIUtils.getHostState()
162              .then(function(state) {
163                if (state === Constants.HOST_STATE_TEXT.off_code) {
164                  $interval.cancel(pollHostStatusTimer);
165                  pollHostStatusTimer = undefined;
166                  deferred.resolve(state);
167                }
168              })
169              .catch(function(error) {
170                $interval.cancel(pollHostStatusTimer);
171                pollHostStatusTimer = undefined;
172                deferred.reject(error);
173              });
174        }, Constants.POLL_INTERVALS.POWER_OP);
175
176        return deferred.promise;
177      }
178      $scope.warmReboot = function() {
179        $scope.loading = true;
180        dataService.setUnreachableState();
181        APIUtils.hostReboot()
182            .then(function(response) {
183              return response;
184            })
185            .then(function(lastStatus) {
186              pollStartTime = new Date();
187              return pollHostStatusTillOff();
188            })
189            .then(function(hostState) {
190              pollStartTime = new Date();
191              return pollHostStatusTillOn();
192            })
193            .then(function(hostState) {
194              $scope.loading = false;
195            })
196            .catch(function(error) {
197              dataService.activateErrorModal({
198                title: Constants.MESSAGES.POWER_OP.WARM_REBOOT_FAILED,
199                description: error.statusText ?
200                    $interpolate(
201                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
202                        {status: error.status, description: error.statusText}) :
203                    error
204              });
205              $scope.loading = false;
206            });
207      };
208      $scope.testState = function() {
209        $timeout(function() {
210          dataService.setPowerOffState();
211          $timeout(function() {
212            dataService.setPowerOnState();
213          }, 2000);
214        }, 1000);
215      };
216      $scope.warmRebootConfirm = function() {
217        if ($scope.confirm) {
218          return;
219        }
220        $scope.confirm = true;
221        $scope.warmboot_confirm = true;
222      };
223
224      $scope.coldReboot = function() {
225        $scope.loading = true;
226        dataService.setUnreachableState();
227        APIUtils.chassisPowerOff()
228            .then(function(state) {
229              return state;
230            })
231            .then(function(lastState) {
232              pollStartTime = new Date();
233              return pollChassisStatusTillOff();
234            })
235            .then(function(chassisState) {
236              return APIUtils.hostPowerOn().then(function(hostState) {
237                return hostState;
238              });
239            })
240            .then(function(hostState) {
241              pollStartTime = new Date();
242              return pollHostStatusTillOn();
243            })
244            .then(function(state) {
245              $scope.loading = false;
246            })
247            .catch(function(error) {
248              dataService.activateErrorModal({
249                title: Constants.MESSAGES.POWER_OP.COLD_REBOOT_FAILED,
250                description: error.statusText ?
251                    $interpolate(
252                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
253                        {status: error.status, description: error.statusText}) :
254                    error
255              });
256              $scope.loading = false;
257            });
258      };
259      $scope.coldRebootConfirm = function() {
260        if ($scope.confirm) {
261          return;
262        }
263        $scope.confirm = true;
264        $scope.coldboot_confirm = true;
265      };
266
267      $scope.orderlyShutdown = function() {
268        $scope.loading = true;
269        dataService.setUnreachableState();
270        APIUtils.hostPowerOff()
271            .then(function(response) {
272              return response;
273            })
274            .then(function(lastStatus) {
275              pollStartTime = new Date();
276              return pollHostStatusTillOff();
277            })
278            .then(function(hostState) {
279              pollStartTime = new Date();
280              return pollChassisStatusTillOff();
281            })
282            .then(function(chassisState) {
283              $scope.loading = false;
284            })
285            .catch(function(error) {
286              dataService.activateErrorModal({
287                title: Constants.MESSAGES.POWER_OP.ORDERLY_SHUTDOWN_FAILED,
288                description: error.statusText ?
289                    $interpolate(
290                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
291                        {status: error.status, description: error.statusText}) :
292                    error
293              });
294              $scope.loading = false;
295            });
296      };
297      $scope.orderlyShutdownConfirm = function() {
298        if ($scope.confirm) {
299          return;
300        }
301        $scope.confirm = true;
302        $scope.orderly_confirm = true;
303      };
304
305      $scope.immediateShutdown = function() {
306        $scope.loading = true;
307        dataService.setUnreachableState();
308        APIUtils.chassisPowerOff()
309            .then(function(response) {
310              return response;
311            })
312            .then(function(lastStatus) {
313              pollStartTime = new Date();
314              return pollChassisStatusTillOff();
315            })
316            .then(function(chassisState) {
317              dataService.setPowerOffState();
318              $scope.loading = false;
319            })
320            .catch(function(error) {
321              dataService.activateErrorModal({
322                title: Constants.MESSAGES.POWER_OP.IMMEDIATE_SHUTDOWN_FAILED,
323                description: error.statusText ?
324                    $interpolate(
325                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
326                        {status: error.status, description: error.statusText}) :
327                    error
328              });
329              $scope.loading = false;
330            });
331      };
332      $scope.immediateShutdownConfirm = function() {
333        if ($scope.confirm) {
334          return;
335        }
336        $scope.confirm = true;
337        $scope.immediately_confirm = true;
338      };
339    }
340  ]);
341})(angular);
342