Add fixes for cold reboot

This fixes the cold reboot issue with the following steps

- It applies the command to shut off the chassis.
- Then verify the chassis is off. It checks for every 5 seconds.
  During this time the spinner displays. A 5min timeout has been
  added.
- Once the chassis is off, it turns on the host.

fixes openbmc/openbmc#2795

Change-Id: I119a1c95e57c10ccee27be1512a1fc38cde307fa
Signed-off-by: Iftekharul Islam <iffy.ryan@ibm.com>
Signed-off-by: CamVan Nguyen <ctnguyen@us.ibm.com>
diff --git a/app/common/directives/app-header.js b/app/common/directives/app-header.js
index 1ba55ba..2a34381 100644
--- a/app/common/directives/app-header.js
+++ b/app/common/directives/app-header.js
@@ -24,7 +24,7 @@
                         if(!userModel.isLoggedIn()){
                             return;
                         }
-                        APIUtils.getHostState(function(status){
+                        APIUtils.getHostState().then(function(status){
                             if(status == 'xyz.openbmc_project.State.Host.HostState.Off'){
                                 dataService.setPowerOffState();
                             }else if(status == 'xyz.openbmc_project.State.Host.HostState.Running'){
@@ -32,6 +32,8 @@
                             }else{
                                 dataService.setBootingState();
                             }
+                        }, function(error){
+                            dataService.activateErrorModal();
                         });
                     }
 
diff --git a/app/common/directives/errors.html b/app/common/directives/errors.html
index 0fd2234..f3e98b6 100644
--- a/app/common/directives/errors.html
+++ b/app/common/directives/errors.html
@@ -1,17 +1,17 @@
 <!-- Unexpected error -->
-<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': display_error}">
+<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': dataService.displayErrorModal}">
     <div class="modal__upload-fail" role="document">
-        <div class="screen-reader-offscreen modal-description">Unexpected error</div><!-- accessibility only; used for screen readers -->
+        <div class="screen-reader-offscreen modal-description">{{dataService.errorModalDetails.title}}</div><!-- accessibility only; used for screen readers -->
         <div class="page-header ">
-            <span class="icon icon__warning inline"><span class="accessible-text" role="alert">Unexpected error</span></span>
-            <h1 class="modal-title h4 inline">Unexpected error</h1>
+            <span class="icon icon__warning inline"><span class="accessible-text" role="alert">{{dataService.errorModalDetails.title}}</span></span>
+            <h1 class="modal-title h4 inline">{{dataService.errorModalDetails.title}}</h1>
         </div>
         <div class="modal__content">
-            <p>Oops! An unexpected error occurred. Record specific details of the issue, then contact your company support services.</p>
+            <p>{{dataService.errorModalDetails.description}}</p>
         </div>
         <div class="modal__button-wrapper">
-            <button class="inline btn-primary" ng-click="display_error = false;">Close</button>
+            <button class="inline btn-primary" ng-click="dataService.deactivateErrorModal()">Close</button>
         </div>
     </div>
 </section>
-<div class="modal-overlay" tabindex="-1" ng-class="{'active': (multi_server_recent)}"></div>
\ No newline at end of file
+<div class="modal-overlay" tabindex="-1" ng-class="{'active': dataService.displayErrorModal}"></div>
diff --git a/app/common/directives/errors.js b/app/common/directives/errors.js
new file mode 100644
index 0000000..2c9b109
--- /dev/null
+++ b/app/common/directives/errors.js
@@ -0,0 +1,18 @@
+window.angular && (function (angular) {
+    'use strict';
+
+    angular
+        .module('app.common.directives')
+        .directive('errors', ['APIUtils', function (APIUtils) {
+            return {
+                'restrict': 'E',
+                'template': require('./errors.html'),
+                'scope': {
+                   'path': '='
+                },
+                'controller': ['$scope','dataService', function($scope, dataService){
+                    $scope.dataService = dataService;
+                }]
+            };
+        }]);
+})(window.angular);
diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
index 1e28127..25cbec9 100644
--- a/app/common/services/api-utils.js
+++ b/app/common/services/api-utils.js
@@ -33,10 +33,11 @@
               LED_STATE: Constants.LED_STATE,
               LED_STATE_TEXT: Constants.LED_STATE_TEXT,
               HOST_SESSION_STORAGE_KEY: Constants.API_CREDENTIALS.host_storage_key,
-              getChassisState: function(callback){
+              getChassisState: function(){
+                var deferred = $q.defer();
                 $http({
                   method: 'GET',
-                  url: DataService.getHost() + "/xyz/openbmc_project/state/chassis0",
+                  url: DataService.getHost() + "/xyz/openbmc_project/state/chassis0/attr/CurrentPowerState",
                   headers: {
                       'Accept': 'application/json',
                       'Content-Type': 'application/json'
@@ -45,15 +46,18 @@
                 }).then(function(response){
                       var json = JSON.stringify(response.data);
                       var content = JSON.parse(json);
-                      callback(content.data.CurrentPowerState);
+                      deferred.resolve(content.data);
                 }, function(error){
                   console.log(error);
+                  deferred.reject(error);
                 });
+                return deferred.promise;
               },
-              getHostState: function(callback){
+              getHostState: function(){
+                var deferred = $q.defer();
                 $http({
                   method: 'GET',
-                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0",
+                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/CurrentHostState",
                   headers: {
                       'Accept': 'application/json',
                       'Content-Type': 'application/json'
@@ -62,10 +66,12 @@
                 }).then(function(response){
                       var json = JSON.stringify(response.data);
                       var content = JSON.parse(json);
-                      callback(content.data.CurrentHostState);
+                      deferred.resolve(content.data);
                 }, function(error){
                   console.log(error);
+                  deferred.reject(error);
                 });
+                return deferred.promise;
               },
               getNetworkInfo: function(){
                 var deferred = $q.defer();
@@ -287,7 +293,8 @@
                   }
                 });
               },
-              chassisPowerOff: function(callback){
+              chassisPowerOff: function(){
+                var deferred = $q.defer();
                 $http({
                   method: 'PUT',
                   url: DataService.getHost() + "/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition",
@@ -300,16 +307,12 @@
                 }).then(function(response){
                       var json = JSON.stringify(response.data);
                       var content = JSON.parse(json);
-                      if(callback){
-                          return callback(content.status);
-                      }
+                      deferred.resolve(content.status);
                 }, function(error){
-                  if(callback){
-                      callback(error);
-                  }else{
-                      console.log(error);
-                  }
+                  console.log(error);
+                  deferred.reject(error);
                 });
+                return deferred.promise;
               },
               setLEDState: function(state, callback){
                 $http({
@@ -359,7 +362,8 @@
                   }
                 });
               },
-              hostPowerOn: function(callback){
+              hostPowerOn: function(){
+                var deferred = $q.defer();
                 $http({
                   method: 'PUT',
                   url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition",
@@ -372,18 +376,15 @@
                 }).then(function(response){
                       var json = JSON.stringify(response.data);
                       var content = JSON.parse(json);
-                      if(callback){
-                          return callback(content.status);
-                      }
+                      deferred.resolve(content.status);
                 }, function(error){
-                  if(callback){
-                      callback(error);
-                  }else{
-                      console.log(error);
-                  }
+                  console.log(error);
+                  deferred.reject(error);
                 });
+                return deferred.promise;
               },
-              hostPowerOff: function(callback){
+              hostPowerOff: function(){
+                var deferred = $q.defer();
                 $http({
                   method: 'PUT',
                   url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition",
@@ -396,18 +397,15 @@
                 }).then(function(response){
                       var json = JSON.stringify(response.data);
                       var content = JSON.parse(json);
-                      if(callback){
-                          return callback(content.status);
-                      }
+                      deferred.resolve(content.status);
                 }, function(error){
-                  if(callback){
-                      callback(error);
-                  }else{
-                      console.log(error);
-                  }
+                  console.log(error);
+                  deferred.reject(error);
                 });
+                return deferred.promise;
               },
-              hostReboot: function(callback){
+              hostReboot: function(){
+                var deferred = $q.defer();
                 $http({
                   method: 'PUT',
                   url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition",
@@ -420,16 +418,13 @@
                 }).then(function(response){
                       var json = JSON.stringify(response.data);
                       var content = JSON.parse(json);
-                      if(callback){
-                          return callback(content.status);
-                      }
+                      deferred.resolve(content.status);
                 }, function(error){
-                  if(callback){
-                      callback(error);
-                  }else{
-                      console.log(error);
-                  }
+                  console.log(error);
+                  deferred.reject(error);
                 });
+
+                return deferred.promise;
               },
               hostShutdown: function(callback){
                 $http({
diff --git a/app/common/services/constants.js b/app/common/services/constants.js
index 0bb2123..21241da 100644
--- a/app/common/services/constants.js
+++ b/app/common/services/constants.js
@@ -27,11 +27,15 @@
                 },
                 CHASSIS_POWER_STATE: {
                     on: 'On',
-                    off: 'Off'
+                    on_code: 'xyz.openbmc_project.State.Chassis.PowerState.On',
+                    off: 'Off',
+                    off_code: 'xyz.openbmc_project.State.Chassis.PowerState.Off'
                 },
                 HOST_STATE_TEXT: {
                     on: 'Running',
+                    on_code: 'xyz.openbmc_project.State.Host.HostState.Running',
                     off: 'Off',
+                    off_code: 'xyz.openbmc_project.State.Host.HostState.Off',
                     booting: 'Quiesced',
                     unreachable: 'Unreachable'
                 },
@@ -107,21 +111,31 @@
                 ],
                 SENSOR_SORT_ORDER_DEFAULT: 8,
                 FIRMWARE: {
-                  ACTIVATE_FIRMWARE: 'xyz.openbmc_project.Software.Activation.RequestedActivations.Active',
-                  FUNCTIONAL_OBJPATH: '/xyz/openbmc_project/software/functional'
+                    ACTIVATE_FIRMWARE: 'xyz.openbmc_project.Software.Activation.RequestedActivations.Active',
+                    FUNCTIONAL_OBJPATH: '/xyz/openbmc_project/software/functional'
                 },
-               POLL_INTERVALS: {
-                  ACTIVATION: 5000
+                POLL_INTERVALS: {
+                    ACTIVATION: 5000,
+                    POWER_OP: 5000,
                 },
-               TIMEOUT: {
-                  ACTIVATION: 1000 * 60 * 10, // 10 mins
+                TIMEOUT: {
+                    ACTIVATION: 1000 * 60 * 10, // 10 mins
+                    CHASSIS_OFF: 1000 * 60 * 5, // 5 mins
+                    HOST_ON: 1000 * 60 * 5, // 5 mins
                 },
                 MESSAGES: {
-                  SENSOR: {
-                    NO_SENSOR_DATA: 'There are no sensors found.',
-                    CRITICAL_NO_SENSOR_DATA: 'There are no sensors in Critical state.',
-                    WARNING_NO_SENSOR_DATA: 'There are no sensors in Warning state.'
-                  }
+                    POLL: {
+                        TIMEOUT: 'Time out. Did not reach power state in allotted time.',
+                    },
+                    SENSOR: {
+                        NO_SENSOR_DATA: 'There are no sensors found.',
+                        CRITICAL_NO_SENSOR_DATA: 'There are no sensors in Critical state.',
+                        WARNING_NO_SENSOR_DATA: 'There are no sensors in Warning state.'
+                    },
+                    ERROR_MODAL: {
+                        TITLE: 'Unexpected error',
+                        DESCRIPTION: 'Oops! An unexpected error occurred. Record specific details of the issue, then contact your company support services.'
+                    }
                 },
                 POWER_CAP_TEXT: {
                     unit: 'W',
diff --git a/app/common/services/dataService.js b/app/common/services/dataService.js
index 201e79c..d84821a 100644
--- a/app/common/services/dataService.js
+++ b/app/common/services/dataService.js
@@ -33,6 +33,10 @@
             this.hostname = "";
             this.mac_address = "";
             this.remote_window_active = false;
+
+            this.displayErrorModal = false;
+            this.errorModalDetails = {};
+
             this.ignoreHttpError = false;
             this.getServerId = function(){
                  return this.host.replace(/^https?\:\/\//ig,"");
@@ -121,6 +125,25 @@
 
                 this.server_health = Constants.SERVER_HEALTH.good;
             }
+
+            this.activateErrorModal = function(data){
+                if(data && data.hasOwnProperty('title')){
+                    this.errorModalDetails.title = data.title;
+                }else{
+                    this.errorModalDetails.title = Constants.MESSAGES.ERROR_MODAL.TITLE;
+                }
+
+                if(data && data.hasOwnProperty('description')){
+                    this.errorModalDetails.description = data.description;
+                }else{
+                    this.errorModalDetails.description = Constants.MESSAGES.ERROR_MODAL.DESCRIPTION;
+                }
+                this.displayErrorModal = true;
+            }
+
+            this.deactivateErrorModal = function(){
+                this.displayErrorModal = false;
+            }
         }]);
 
 })(window.angular);