Procházet zdrojové kódy

AMBARI-8531 Modifications of rolling upgrade process. (atkach)

Andrii Tkach před 10 roky
rodič
revize
9b0c3ec030

+ 11 - 4
ambari-web/app/app.js

@@ -34,11 +34,18 @@ module.exports = Em.Application.create({
   }),
   }),
   isAdmin: false,
   isAdmin: false,
   isOperator: false,
   isOperator: false,
+
   /**
   /**
-   * indicate whether stack upgrade is running or not
-   * @type {boolean}
+   * state of stack upgrade process
+   * states:
+   *  - INIT
+   *  - IN_PROGRESS
+   *  - STOPPED
+   *  - COMPLETED
+   * @type {String}
    */
    */
-  isUpgrading: false,
+  upgradeState: 'INIT',
+
   /**
   /**
    * compute user access rights by permission type
    * compute user access rights by permission type
    * types:
    * types:
@@ -51,7 +58,7 @@ module.exports = Em.Application.create({
    * @return {boolean}
    * @return {boolean}
    */
    */
   isAccessible: function (type) {
   isAccessible: function (type) {
-    if (this.get('isUpgrading') && !type.contains('upgrade_')) {
+    if (this.get('upgradeState') !== 'INIT' && !type.contains('upgrade_')) {
       return false;
       return false;
     }
     }
 
 

+ 78 - 1
ambari-web/app/assets/data/stack_versions/stack_version_all.json

@@ -5,7 +5,7 @@
       "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2",
       "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2",
       "ClusterStackVersions" : {
       "ClusterStackVersions" : {
         "cluster_name" : "1",
         "cluster_name" : "1",
-        "id" : 2,
+        "id" : 1,
         "stack" : "HDP",
         "stack" : "HDP",
         "state" : "CURRENT",
         "state" : "CURRENT",
         "version" : "2.2",
         "version" : "2.2",
@@ -77,6 +77,83 @@
           ]
           ]
         }
         }
       ]
       ]
+    },
+    {
+      "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2",
+      "ClusterStackVersions" : {
+        "cluster_name" : "1",
+        "id" : 2,
+        "stack" : "HDP",
+        "state" : "INSTALLED",
+        "version" : "2.2",
+        "host_states" : {
+          "CURRENT" : [ ],
+          "INSTALLED" : [
+            "ab3test-2.c.pramod-thangali.internal"
+          ],
+          "INSTALLING" : [ ],
+          "INSTALL_FAILED" : [ ],
+          "UPGRADED" : [ ],
+          "UPGRADE_FAILED" : [ ],
+          "UPGRADING" : [ ]
+        }
+      },
+      "repository_versions" : [
+        {
+          "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2/repository_versions/1",
+          "RepositoryVersions" : {
+            "display_name" : "HDP 2.2.2",
+            "id" : 2,
+            "repository_version" : "2.2.2.1-885",
+            "stack_name" : "HDP",
+            "stack_version" : "2.2",
+            "upgrade_pack" : "upgrade-2.2"
+          },
+          "operating_systems" : [
+            {
+              "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2/repository_versions/1/operating_systems/redhat6",
+              "OperatingSystems" : {
+                "os_type" : "redhat6",
+                "repository_version_id" : 2,
+                "stack_name" : "HDP",
+                "stack_version" : "2.2"
+              },
+              "repositories" : [
+                {
+                  "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2/repository_versions/1/operating_systems/redhat6/repositories/HDP-2.2",
+                  "Repositories" : {
+                    "base_url" : "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0",
+                    "default_base_url" : "",
+                    "latest_base_url" : "",
+                    "mirrors_list" : "",
+                    "os_type" : "redhat6",
+                    "repo_id" : "HDP-2.2",
+                    "repo_name" : "HDP",
+                    "repository_version_id" : 2,
+                    "stack_name" : "HDP",
+                    "stack_version" : "2.2"
+                  }
+                },
+                {
+                  "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2/repository_versions/1/operating_systems/redhat6/repositories/HDP-UTILS-1.1.0.20",
+                  "Repositories" : {
+                    "base_url" : "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0",
+                    "default_base_url" : "",
+                    "latest_base_url" : "",
+                    "mirrors_list" : "",
+                    "os_type" : "redhat6",
+                    "repo_id" : "HDP-UTILS-1.1.0.20",
+                    "repo_name" : "HDP-UTILS",
+                    "repository_version_id" : 2,
+                    "stack_name" : "HDP",
+                    "stack_version" : "2.2"
+                  }
+                }
+              ]
+            }
+          ]
+        }
+      ]
     }
     }
   ]
   ]
 }
 }

+ 106 - 57
ambari-web/app/assets/data/stack_versions/upgrade.json

@@ -1,70 +1,119 @@
 {
 {
-  "items": [
+  "Upgrade" : {
+    "cluster_name" : "c1",
+    "id" : 1
+  },
+  "upgrade_groups" : [
     {
     {
-      "UpgradeItem": {
-        "upgrade_item_id": 1,
-        "step_index": 1,
-        "status": "COMPLETED",
-        "stage_id": 124321,
-        "command": "Restart Zookeeper Server on host1",
-        "type": "auto",
-        "description": ""
-      }
+      "UpgradeGroup" : {
+        "group_id" : 1,
+        "name" : "ZOOKEEPER",
+        "state" : "COMPLETED",
+        "title" : "Upgrade Zookeepers",
+        "upgrade_id" : 1,
+        "progress": 100
+      },
+      "upgrade_items" : [
+        {
+          "UpgradeItem" : {
+            "group_id" : 1,
+            "id" : 1,
+            "upgrade_id" : 1,
+            "state": "COMPLETED"
+          }
+        },
+        {
+          "UpgradeItem" : {
+            "group_id" : 1,
+            "id" : 2,
+            "upgrade_id" : 1,
+            "state": "COMPLETED"
+          }
+        }
+      ]
     },
     },
     {
     {
-      "UpgradeItem": {
-        "upgrade_item_id": 2,
-        "step_index": 2,
-        "status": "WARNING",
-        "stage_id": 124321,
-        "command": "Restart Zookeeper Server on host2",
-        "type": "auto",
-        "description": ""
-      }
+      "UpgradeGroup" : {
+        "group_id" : 2,
+        "name" : "CM",
+        "state" : "IN_PROGRESS",
+        "title" : "Upgrade Core Master",
+        "upgrade_id" : 1,
+        "progress": 4
+      },
+      "upgrade_items" : [
+        {
+          "UpgradeItem" : {
+            "group_id" : 2,
+            "id" : 1,
+            "upgrade_id" : 1,
+            "state": "IN_PROGRESS",
+            "name": "Upgrade DATANODE"
+          }
+        }
+      ]
     },
     },
     {
     {
-      "UpgradeItem": {
-        "upgrade_item_id": 3,
-        "step_index": 3,
-        "status": "IN_PROGRESS",
-        "stage_id": 124321,
-        "command": "Run manual steps",
-        "type": "manual",
-        "description": "List of manual steps"
-      }
+      "UpgradeGroup" : {
+        "group_id" : 3,
+        "name" : "CL",
+        "state" : "FAILED",
+        "title" : "Upgrade Core Slaves",
+        "upgrade_id" : 1,
+        "progress": 1
+      },
+      "upgrade_items" : [
+        {
+          "UpgradeItem" : {
+            "group_id" : 3,
+            "id" : 1,
+            "upgrade_id" : 1,
+            "state": "FAILED",
+            "name": "Upgrade DATANODE"
+          }
+        }
+      ]
     },
     },
     {
     {
-      "UpgradeItem": {
-        "upgrade_item_id": 4,
-        "step_index": 4,
-        "status": "PENDING",
-        "stage_id": 124321,
-        "command": "Restart Datanode on 2 hosts",
-        "type": "auto",
-        "description": ""
-      }
+      "UpgradeGroup" : {
+        "group_id" : 4,
+        "name" : "MS",
+        "state" : "IN_PROGRESS",
+        "title" : "Manual Step",
+        "upgrade_id" : 1,
+        "progress": 0,
+        "type": "manual"
+      },
+      "upgrade_items" : [
+        {
+          "UpgradeItem" : {
+            "group_id" : 4,
+            "id" : 1,
+            "upgrade_id" : 1,
+            "state": "IN_PROGRESS"
+          }
+        }
+      ]
     },
     },
     {
     {
-      "UpgradeItem": {
-        "upgrade_item_id": 5,
-        "step_index": 5,
-        "status": "PENDING",
-        "stage_id": 124321,
-        "command": "Restart Datanode on 2 hosts",
-        "type": "auto",
-        "description": ""
-      }
-    },
-    {
-      "UpgradeItem": {
-        "upgrade_item_id": 6,
-        "step_index": 6,
-        "status": "FAILED",
-        "stage_id": 124321,
-        "command": "Restart Zookeeper Server on host3",
-        "type": "auto",
-        "description": ""
-      }
+      "UpgradeGroup" : {
+        "group_id" : 5,
+        "name" : "UH",
+        "state" : "PENDING",
+        "title" : "Upgrade Hive",
+        "upgrade_id" : 1,
+        "progress": 0
+      },
+      "upgrade_items" : [
+        {
+          "UpgradeItem" : {
+            "group_id" : 5,
+            "id" : 1,
+            "upgrade_id" : 1,
+            "state": "PENDING"
+          }
+        }
+      ]
     }
     }
   ]
   ]
 }
 }

+ 57 - 37
ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js

@@ -17,22 +17,42 @@
  */
  */
 
 
 var App = require('app');
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 
 App.MainAdminStackAndUpgradeController = Em.Controller.extend({
 App.MainAdminStackAndUpgradeController = Em.Controller.extend({
   name: 'mainAdminStackAndUpgradeController',
   name: 'mainAdminStackAndUpgradeController',
 
 
+  /**
+   * @type {Object|null}
+   */
   serviceToInstall: null,
   serviceToInstall: null,
-  upgradeTasks: [],
+
+  /**
+   * @type {Array}
+   */
+  upgradeGroups: [],
+
+  /**
+   * TODO should have actual value from call that start upgrade
+   * @type {Number|null}
+   */
+  upgradeId: 1,
 
 
   /**
   /**
    * version that currently applied to server
    * version that currently applied to server
+   * @type {Object|null}
    */
    */
   currentVersion: null,
   currentVersion: null,
+
   /**
   /**
    * versions to which cluster could be upgraded
    * versions to which cluster could be upgraded
+   * @type {Array}
    */
    */
   targetVersions: [],
   targetVersions: [],
 
 
+  /**
+   * @type {Array}
+   */
   services: function() {
   services: function() {
     return App.StackService.find().map(function(s) {
     return App.StackService.find().map(function(s) {
       s.set('isInstalled', App.Service.find().someProperty('serviceName', s.get('serviceName')));
       s.set('isInstalled', App.Service.find().someProperty('serviceName', s.get('serviceName')));
@@ -70,28 +90,33 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend({
    */
    */
   loadVersionsInfoSuccessCallback: function (data) {
   loadVersionsInfoSuccessCallback: function (data) {
     var current = data.items.findProperty('ClusterStackVersions.state', 'CURRENT');
     var current = data.items.findProperty('ClusterStackVersions.state', 'CURRENT');
-    var target = data.items.without(current);
+    var currentVersion = current.repository_versions[0].RepositoryVersions.repository_version;
+    var targetVersions = data.items.without(current)
+      .filter(function (version) {
+        var repositoryVersion = version.repository_versions[0].RepositoryVersions.repository_version;
+        //Only higher versions that have already been installed to all the hosts are shown
+        return (version.ClusterStackVersions.state === 'INSTALLED' &&
+               stringUtils.compareVersions(repositoryVersion, currentVersion) === 1);
+      }).map(function (version) {
+        return version.ClusterStackVersions;
+      });
 
 
     this.set('currentVersion', current.ClusterStackVersions);
     this.set('currentVersion', current.ClusterStackVersions);
-    this.set('targetVersions', target.map(function (ver) {
-      return ver.ClusterStackVersions;
-    }));
+    this.set('targetVersions', targetVersions);
   },
   },
 
 
   /**
   /**
    * load upgrade tasks by upgrade id
    * load upgrade tasks by upgrade id
    * @return {$.ajax}
    * @return {$.ajax}
    */
    */
-  loadUpgradeTasks: function () {
-    //TODO should make call with actual upgrade id
-    var upgradeId = 1;
+  loadUpgradeData: function () {
     return App.ajax.send({
     return App.ajax.send({
-      name: 'admin.upgrade.tasks',
+      name: 'admin.upgrade.data',
       sender: this,
       sender: this,
       data: {
       data: {
-        id: upgradeId
+        id: this.get('upgradeId')
       },
       },
-      success: 'loadUpgradeTasksSuccessCallback'
+      success: 'loadUpgradeDataSuccessCallback'
     });
     });
   },
   },
 
 
@@ -99,37 +124,45 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend({
    * parse and push upgrade tasks to controller
    * parse and push upgrade tasks to controller
    * @param data
    * @param data
    */
    */
-  loadUpgradeTasksSuccessCallback: function (data) {
-    this.set("upgradeTasks", data.items.map(function (item) {
-      return item.UpgradeItem;
-    }));
+  loadUpgradeDataSuccessCallback: function (data) {
+    this.set("upgradeGroups", data.upgrade_groups);
   },
   },
 
 
   /**
   /**
-   * start cluster downgrade
+   * make call to start downgrade process
    */
    */
   downgrade: function () {
   downgrade: function () {
-    //TODO start actual downgrade
+    //TODO start downgrade
   },
   },
+
   /**
   /**
-   * start cluster upgrade
+   * make call to start upgrade process and show popup with current progress
    */
    */
   upgrade: function () {
   upgrade: function () {
-    //TODO start actual upgrade
-    this.loadUpgradeTasks();
+    //TODO start upgrade
+    this.loadUpgradeData();
     this.openUpgradeDialog();
     this.openUpgradeDialog();
   },
   },
+
   /**
   /**
-   * resume upgrade process
+   * make call to resume upgrade process and show popup with current progress
    */
    */
   resumeUpgrade: function () {
   resumeUpgrade: function () {
     //TODO resume upgrade
     //TODO resume upgrade
   },
   },
+
   /**
   /**
-   * finish upgrade process
+   * make call to stop upgrade process
+   */
+  stopUpgrade: function () {
+    //TODO stop upgrade
+  },
+
+  /**
+   * make call to finish upgrade process
    */
    */
   finalize: function () {
   finalize: function () {
-    //TODO start actual finalize
+    //TODO start finalize
   },
   },
 
 
   /**
   /**
@@ -137,19 +170,6 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend({
    * @return {App.ModalPopup}
    * @return {App.ModalPopup}
    */
    */
   openUpgradeDialog: function () {
   openUpgradeDialog: function () {
-    var upgradeVersion = 'HDP-2.2.1';
-
-    return App.ModalPopup.show({
-      header: Em.I18n.t('admin.stackUpgrade.dialog.header').format(upgradeVersion),
-      bodyClass: Em.View.extend({
-        controller: this,
-        templateName: require('templates/main/admin/stack_upgrade/stack_upgrade_dialog'),
-        tasks: function () {
-          return this.get('controller.upgradeTasks');
-        }.property('controller.upgradeTasks')
-      }),
-      primary: null,
-      secondary: null
-    });
+    App.router.transitionTo('admin.stackUpgrade');
   }
   }
 });
 });

+ 13 - 3
ambari-web/app/messages.js

@@ -239,6 +239,7 @@ Em.I18n.translations = {
   'common.install': "Install",
   'common.install': "Install",
   'common.alertDefinition': "Alert Definition",
   'common.alertDefinition': "Alert Definition",
   'common.prerequisites': 'Prerequisites',
   'common.prerequisites': 'Prerequisites',
+  'common.finalize': "Finalize",
 
 
   'passiveState.turnOn':'Turn On Maintenance Mode',
   'passiveState.turnOn':'Turn On Maintenance Mode',
   'passiveState.turnOff':'Turn Off Maintenance Mode',
   'passiveState.turnOff':'Turn Off Maintenance Mode',
@@ -1268,15 +1269,24 @@ Em.I18n.translations = {
   'admin.stackUpgrade.state.available': "Upgrade Available",
   'admin.stackUpgrade.state.available': "Upgrade Available",
   'admin.stackUpgrade.state.notAvailable': "No Upgrade Available",
   'admin.stackUpgrade.state.notAvailable': "No Upgrade Available",
   'admin.stackUpgrade.state.resume': "Resume Upgrade",
   'admin.stackUpgrade.state.resume': "Resume Upgrade",
-  'admin.stackUpgrade.state.finalize': "Finalize",
+  'admin.stackUpgrade.state.inProgress': "Upgrade in progress",
+  'admin.stackUpgrade.state.stopped': "Upgrade Stopped",
+  'admin.stackUpgrade.state.completed': "Upgrade Finished",
+  'admin.stackUpgrade.state.upgrading': "Upgrading...",
   'admin.stackUpgrade.hosts': "hosts",
   'admin.stackUpgrade.hosts': "hosts",
   'admin.stackUpgrade.host': "host",
   'admin.stackUpgrade.host': "host",
   'admin.stackUpgrade.dialog.header': "Upgrade to {0} in progress",
   'admin.stackUpgrade.dialog.header': "Upgrade to {0} in progress",
   'admin.stackUpgrade.dialog.operationFailed': "This operation failed.",
   'admin.stackUpgrade.dialog.operationFailed': "This operation failed.",
-  'admin.stackUpgrade.dialog.errorLink': "See error message",
   'admin.stackUpgrade.dialog.stop': "Stop Upgrade",
   'admin.stackUpgrade.dialog.stop': "Stop Upgrade",
-  'admin.stackUpgrade.dialog.continue': "Ignore and Continue",
+  'admin.stackUpgrade.dialog.continue': "Ignore and Proceed",
+  'admin.stackUpgrade.dialog.inProgress': "Currently running:",
+  'admin.stackUpgrade.dialog.keepRunning': "Keep running Upgrade in background",
+  'admin.stackUpgrade.dialog.failed': "Failed on:",
+  'admin.stackUpgrade.dialog.manual': "Manual steps required",
   'admin.stackUpgrade.dialog.manualDone': "I have preformed the manual steps above.",
   'admin.stackUpgrade.dialog.manualDone': "I have preformed the manual steps above.",
+  'admin.stackUpgrade.dialog.close': "Upgrade is in progress. \n" +
+    "Do you want to keep running Upgrade in the background," +
+    " or do you want to stop the Upgrade? If you stop the Upgrade, you can resume later.",
 
 
   'services.service.start':'Start',
   'services.service.start':'Start',
   'services.service.stop':'Stop',
   'services.service.stop':'Stop',

+ 2 - 0
ambari-web/app/routes/main.js

@@ -520,6 +520,8 @@ module.exports = Em.Route.extend({
         router.get('mainAdminController').connectOutlet('mainAdminStackAndUpgrade');
         router.get('mainAdminController').connectOutlet('mainAdminStackAndUpgrade');
       }
       }
     }),
     }),
+    stackUpgrade: require('routes/stack_upgrade_routes'),
+
     adminStackVersions: Em.Route.extend({
     adminStackVersions: Em.Route.extend({
       route: '/versions',
       route: '/versions',
       index: Em.Route.extend({
       index: Em.Route.extend({

+ 70 - 0
ambari-web/app/routes/stack_upgrade_routes.js

@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var App = require('app');
+
+module.exports = App.WizardRoute.extend({
+  route: 'stack/upgrade',
+
+  enter: function (router) {
+    console.log('in /admin/stack/upgrade:enter');
+    Ember.run.next(function () {
+      var upgradeVersion = 'HDP-2.2.1';
+      App.router.get('updateController').set('isWorking', false);
+
+      return App.ModalPopup.show({
+        header: Em.I18n.t('admin.stackUpgrade.dialog.header').format(upgradeVersion),
+        bodyClass: Em.View.extend({
+          controllerBinding: 'App.router.mainAdminStackAndUpgradeController',
+          templateName: require('templates/main/admin/stack_upgrade/stack_upgrade_dialog'),
+          willInsertElement: function () {
+            this.startPolling();
+          },
+          /**
+           * start polling upgrade tasks data
+           */
+          startPolling: function () {
+            this.get('controller').loadUpgradeData();
+          },
+          groups: function () {
+            return this.get('controller.upgradeGroups');
+          }.property('controller.upgradeGroups')
+        }),
+        primary: null,
+        secondary: null,
+        onClose: function() {
+          App.router.get('updateController').set('isWorking', true);
+          App.router.transitionTo('main.admin.stackAndUpgrade');
+          this._super();
+          App.ModalPopup.show({
+            header: Em.I18n.t('admin.stackUpgrade.state.inProgress'),
+            body: Em.I18n.t('admin.stackUpgrade.dialog.close'),
+            primary: Em.I18n.t('admin.stackUpgrade.dialog.keepRunning'),
+            secondary: Em.I18n.t('admin.stackUpgrade.dialog.stop'),
+            secondaryClass: 'btn-danger',
+            showCloseButton: false,
+            onSecondary: function() {
+              App.router.get('mainAdminStackAndUpgradeController').stopUpgrade();
+              this._super();
+            }
+          })
+        }
+      });
+    });
+  }
+});

+ 3 - 0
ambari-web/app/styles/application.less

@@ -6563,6 +6563,9 @@ i.icon-asterisks {
         line-height: 30px;
         line-height: 30px;
       }
       }
     }
     }
+    .progress {
+      margin-bottom: 0;
+    }
   }
   }
   .task-list>div {
   .task-list>div {
     padding: 5px;
     padding: 5px;

+ 1 - 1
ambari-web/app/templates/common/modal_popup.hbs

@@ -55,7 +55,7 @@
           <button class="btn" {{bindAttr disabled="view.disableThird"}} {{action onThird target="view"}}>{{view.third}}</button>
           <button class="btn" {{bindAttr disabled="view.disableThird"}} {{action onThird target="view"}}>{{view.third}}</button>
         {{/if}}
         {{/if}}
         {{#if view.secondary}}
         {{#if view.secondary}}
-          <button class="btn" {{bindAttr disabled="view.disableSecondary"}} {{action onSecondary target="view"}}>{{view.secondary}}</button>
+          <button {{bindAttr disabled="view.disableSecondary" class=":btn view.secondaryClass"}} {{action onSecondary target="view"}}>{{view.secondary}}</button>
         {{/if}}
         {{/if}}
         {{#if view.primary}}
         {{#if view.primary}}
           <button {{bindAttr disabled="view.disablePrimary" class=":btn view.primaryClass"}} {{action onPrimary target="view"}}>{{view.primary}}</button>
           <button {{bindAttr disabled="view.disablePrimary" class=":btn view.primaryClass"}} {{action onPrimary target="view"}}>{{view.primary}}</button>

+ 2 - 2
ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_dialog.hbs

@@ -31,8 +31,8 @@
   </div>
   </div>
 
 
   <div class="task-list">
   <div class="task-list">
-    {{#each task in view.tasks}}
-      {{view App.upgradeTaskView contentBinding="task"}}
+    {{#each group in view.groups}}
+      {{view App.upgradeTaskView contentBinding="group"}}
     {{/each}}
     {{/each}}
   </div>
   </div>
 </div>
 </div>

+ 32 - 16
ambari-web/app/templates/main/admin/stack_upgrade/upgrade_task.hbs

@@ -16,33 +16,49 @@
 * limitations under the License.
 * limitations under the License.
 }}
 }}
 
 
-<i {{bindAttr class="view.iconClass"}}></i><span>{{view.content.command}}</span>
+
+<div class="row-fluid">
+  <div class="span6"><i {{bindAttr class="view.iconClass"}}></i><a>{{view.content.UpgradeGroup.title}}</a></div>
+  <div class="span4">
+    {{#if view.showProgressBar}}
+      <div class="progress progress-striped active">
+        <div class="bar" {{bindAttr style="view.progressWidth"}}></div>
+      </div>
+    {{/if}}
+  </div>
+  <div class="offset2"></div>
+</div>
+{{#if view.isInProgress}}
+  <div class="box task-details">
+    <div>
+      {{t admin.stackUpgrade.dialog.inProgress}}&nbsp;
+      <a href>{{view.runningItem.UpgradeItem.name}}</a>
+    </div>
+  </div>
+{{/if}}
 {{#if view.isFailed}}
 {{#if view.isFailed}}
   <div class="box task-details">
   <div class="box task-details">
     <div>
     <div>
-      {{t admin.stackUpgrade.dialog.operationFailed}}&nbsp;
-      <a href>{{t admin.stackUpgrade.dialog.errorLink}}</a>
+      {{t admin.stackUpgrade.dialog.failed}}&nbsp;
+      <a href>{{view.failedItem.UpgradeItem.name}}</a>
     </div>
     </div>
     <div class="button-row">
     <div class="button-row">
-      <button class="btn">{{t admin.stackUpgrade.dialog.continue}}</button>
       <button class="btn btn-danger">{{t admin.stackUpgrade.dialog.stop}}</button>
       <button class="btn btn-danger">{{t admin.stackUpgrade.dialog.stop}}</button>
-      <button class="btn btn-primary">{{t common.retry}}</button>
+      <button class="btn btn-warning">{{t admin.stackUpgrade.dialog.continue}}</button>
+      <button class="btn">{{t common.retry}}</button>
     </div>
     </div>
   </div>
   </div>
 {{/if}}
 {{/if}}
 {{#if view.isManualOpened}}
 {{#if view.isManualOpened}}
-  <div class="task-details">
-    <div class="alert alert-info">
-      {{view.content.description}}
+  <div class="box task-details">
+    <p><strong>{{t admin.stackUpgrade.dialog.manual}}</strong></p>
+    <div class="message">
+      {{view Em.Checkbox checkedBinding="view.isManualDone"}}
+      {{t admin.stackUpgrade.dialog.manualDone}}
     </div>
     </div>
-    <div class="row-fluid">
-      <div class="span10 message">
-        {{view Em.Checkbox valueBinding="view.isManualDone"}}
-        {{t admin.stackUpgrade.dialog.manualDone}}
-      </div>
-      <div class="span2">
-        <button class="btn btn-success pull-right">{{t common.proceed}}</button>
-      </div>
+    <div class="button-row">
+      <button class="btn btn-danger">{{t admin.stackUpgrade.dialog.stop}}</button>
+      <button class="btn btn-success" {{bindAttr disabled="view.isManualProceedDisabled"}}>{{t common.proceed}}</button>
     </div>
     </div>
   </div>
   </div>
 {{/if}}
 {{/if}}

+ 2 - 2
ambari-web/app/utils/ajax/ajax.js

@@ -1292,8 +1292,8 @@ var urls = {
     'real': '/clusters/{cluster}/requests/{requestId}?fields=tasks/*',
     'real': '/clusters/{cluster}/requests/{requestId}?fields=tasks/*',
     'mock': '/data/wizard/{mock}'
     'mock': '/data/wizard/{mock}'
   },
   },
-  'admin.upgrade.tasks': {
-    'real': '/clusters/{clusterName}/upgrades/{id}/upgrade_items',
+  'admin.upgrade.data': {
+    'real': '/clusters/{clusterName}/upgrades/{id}?fields=upgrade_groups/UpgradeGroup,upgrade_groups/upgrade_items',
     'mock': '/data/stack_versions/upgrade.json'
     'mock': '/data/stack_versions/upgrade.json'
   },
   },
   'admin.stack_versions.all': {
   'admin.stack_versions.all': {

+ 1 - 0
ambari-web/app/views/common/modal_popup.js

@@ -34,6 +34,7 @@ App.ModalPopup = Ember.View.extend({
   disableSecondary: false,
   disableSecondary: false,
   disableThird: false,
   disableThird: false,
   primaryClass: 'btn-success',
   primaryClass: 'btn-success',
+  secondaryClass: '',
   onPrimary: function () {
   onPrimary: function () {
     this.hide();
     this.hide();
   },
   },

+ 61 - 10
ambari-web/app/views/main/admin/stack_and_upgrade_view.js

@@ -22,19 +22,42 @@ var stringUtils = require('utils/string_utils');
 App.MainAdminStackAndUpgradeView = Em.View.extend({
 App.MainAdminStackAndUpgradeView = Em.View.extend({
   templateName: require('templates/main/admin/stack_and_upgrade'),
   templateName: require('templates/main/admin/stack_and_upgrade'),
 
 
+  /**
+   * label with number of HEALTHY hosts
+   * @type {String}
+   */
   hostsOnlineLabel: function () {
   hostsOnlineLabel: function () {
     var hostsCountMap = App.router.get('mainHostController.hostsCountMap');
     var hostsCountMap = App.router.get('mainHostController.hostsCountMap');
     return Em.I18n.t('admin.stackUpgrade.hostsOnline').format(hostsCountMap.HEALTHY, hostsCountMap.TOTAL);
     return Em.I18n.t('admin.stackUpgrade.hostsOnline').format(hostsCountMap.HEALTHY, hostsCountMap.TOTAL);
   }.property('App.router.mainHostController.hostsCountMap'),
   }.property('App.router.mainHostController.hostsCountMap'),
 
 
+  /**
+   * label that depict current upgrade process state
+   * @type {String}
+   */
   upgradeStateLabel: function () {
   upgradeStateLabel: function () {
-    return "";
-  }.property(),
+    switch (App.get('upgradeState')) {
+      case 'INIT':
+        return (this.get('controller.targetVersions.length') > 0) ? Em.I18n.t('admin.stackUpgrade.state.available') : "";
+      case 'IN_PROGRESS':
+        return Em.I18n.t('admin.stackUpgrade.state.inProgress');
+      case 'STOPPED':
+        return Em.I18n.t('admin.stackUpgrade.state.stopped');
+      case 'COMPLETED':
+        return Em.I18n.t('admin.stackUpgrade.state.completed');
+      default:
+        return "";
+    }
+  }.property('App.upgradeState', 'controller.targetVersions'),
 
 
   willInsertElement: function () {
   willInsertElement: function () {
     if (App.get('supports.stackUpgrade')) this.get('controller').loadVersionsInfo();
     if (App.get('supports.stackUpgrade')) this.get('controller').loadVersionsInfo();
   },
   },
 
 
+  /**
+   * box that display info about current version
+   * @type {Em.View}
+   */
   sourceVersionView: App.UpgradeVersionBoxView.extend({
   sourceVersionView: App.UpgradeVersionBoxView.extend({
     version: function () {
     version: function () {
       return this.get('controller.currentVersion');
       return this.get('controller.currentVersion');
@@ -50,6 +73,11 @@ App.MainAdminStackAndUpgradeView = Em.View.extend({
       return this.get('version.current_hosts.length');
       return this.get('version.current_hosts.length');
     }.property('version.current_hosts.length')
     }.property('version.current_hosts.length')
   }),
   }),
+
+  /**
+   * box that display info about target versions
+   * @type {Em.View}
+   */
   targetVersionView: App.UpgradeVersionBoxView.extend({
   targetVersionView: App.UpgradeVersionBoxView.extend({
     versions: function () {
     versions: function () {
       return this.get('controller.targetVersions');
       return this.get('controller.targetVersions');
@@ -71,19 +99,42 @@ App.MainAdminStackAndUpgradeView = Em.View.extend({
         }
         }
       });
       });
     }.property('versions.length'),
     }.property('versions.length'),
+
+    /**
+     * button properties:
+     * - method of controller which will be called on click <code>method</code>
+     * - label <code>label</code>
+     * @type {Object}
+     */
     action: function () {
     action: function () {
-      var methodName = null,
-          labelName = null,
+      var method = null,
+          label = "",
           versions = this.get('versions');
           versions = this.get('versions');
-      if (versions.length > 0) {
-        labelName = Em.I18n.t('common.upgrade');
-        methodName = 'upgrade';
+      switch (App.get('upgradeState')) {
+        case 'INIT':
+          if (this.get('versions.length') > 0) {
+            label = Em.I18n.t('common.upgrade');
+            method = 'upgrade';
+          }
+          break;
+        case 'IN_PROGRESS':
+          label = Em.I18n.t('admin.stackUpgrade.state.upgrading');
+          method = 'openUpgradeDialog';
+          break;
+        case 'STOPPED':
+          label = Em.I18n.t('admin.stackUpgrade.state.resume');
+          method = 'resumeUpgrade';
+          break;
+        case 'COMPLETED':
+          label = Em.I18n.t('common.finalize');
+          method = 'finalize';
+          break;
       }
       }
       return {
       return {
-        method: methodName,
-        label: labelName
+        method: method,
+        label: label
       };
       };
-    }.property('versions.length')
+    }.property('versions.length', 'App.upgradeState')
   })
   })
 });
 });
 
 

+ 58 - 13
ambari-web/app/views/main/admin/stack_upgrade/upgrade_task_view.js

@@ -23,41 +23,86 @@ App.upgradeTaskView = Em.View.extend({
   templateName: require('templates/main/admin/stack_upgrade/upgrade_task'),
   templateName: require('templates/main/admin/stack_upgrade/upgrade_task'),
 
 
   /**
   /**
-   * @type {object|null}
+   * relation map between status and icon class
+   * @type {Object}
    */
    */
-  task: null,
-
   statusIconMap: {
   statusIconMap: {
     'COMPLETED': 'icon-ok',
     'COMPLETED': 'icon-ok',
     'WARNING': 'icon-warning-sign',
     'WARNING': 'icon-warning-sign',
     'FAILED': 'icon-warning-sign',
     'FAILED': 'icon-warning-sign',
-    'PENDING': 'icon-cog'
+    'PENDING': 'icon-cog',
+    'IN_PROGRESS': 'icon-cogs'
   },
   },
 
 
   /**
   /**
-   * @type {boolean}
+   * @type {Boolean}
    */
    */
   isManualDone: false,
   isManualDone: false,
 
 
+  /**
+   * @type {Boolean}
+   */
+  isManualProceedDisabled: function () {
+    return !this.get('isManualDone');
+  }.property('isManualDone'),
+
   /**
   /**
    * @type {string}
    * @type {string}
    */
    */
   iconClass: function () {
   iconClass: function () {
-    return this.get('statusIconMap')[this.get('content.status')] || 'icon-question-sign';
-  }.property('content.status'),
+    return this.get('statusIconMap')[this.get('content.UpgradeGroup.state')] || 'icon-question-sign';
+  }.property('content.UpgradeGroup.state'),
 
 
   /**
   /**
-   * @type {boolean}
+   * @type {Boolean}
    */
    */
   isFailed: function () {
   isFailed: function () {
-    return this.get('content.status') === 'FAILED';
-  }.property('content.status'),
+    return this.get('content.UpgradeGroup.state') === 'FAILED';
+  }.property('content.UpgradeGroup.state'),
+
+  /**
+   * @type {Boolean}
+   */
+  showProgressBar: function () {
+    return ['IN_PROGRESS', 'FAILED'].contains(this.get('content.UpgradeGroup.state')) && this.get('content.UpgradeGroup.type') !== 'manual';
+  }.property('content.UpgradeGroup.state'),
+
+  /**
+   * @type {Boolean}
+   */
+  isInProgress: function () {
+    return this.get('content.UpgradeGroup.state') === 'IN_PROGRESS' && this.get('content.UpgradeGroup.type') !== 'manual';
+  }.property('content.UpgradeGroup.state'),
+
+  /**
+   * width style of progress bar
+   * @type {String}
+   */
+  progressWidth: function () {
+    return "width:" + this.get('content.UpgradeGroup.progress') + '%;';
+  }.property('content.UpgradeGroup.progress'),
+
+  /**
+   * if upgrade group is in progress it should have currently running item
+   * @type {Object|null}
+   */
+  runningItem: function () {
+    return this.get('content.upgrade_items').findProperty('UpgradeItem.state', 'IN_PROGRESS');
+  }.property('content.upgrade_items.@each.UpgradeItem.state'),
+
+  /**
+   * if upgrade group is failed it should have failed item
+   * @type {Object|null}
+   */
+  failedItem: function () {
+    return this.get('content.upgrade_items').findProperty('UpgradeItem.state', 'FAILED');
+  }.property('content.upgrade_items.@each.UpgradeItem.state'),
 
 
   /**
   /**
-   * @type {boolean}
+   * @type {Boolean}
    */
    */
   isManualOpened: function () {
   isManualOpened: function () {
     //TODO modify logic according to actual API
     //TODO modify logic according to actual API
-    return this.get('content.status') === 'IN_PROGRESS' && this.get('content.type') === 'manual'
-  }.property('content.status', 'content.type')
+    return this.get('content.UpgradeGroup.state') === 'IN_PROGRESS' && this.get('content.UpgradeGroup.type') === 'manual'
+  }.property('content.UpgradeGroup.state', 'content.UpgradeGroup.type')
 });
 });

+ 13 - 13
ambari-web/test/app_test.js

@@ -464,72 +464,72 @@ describe('App', function () {
 
 
   describe("#isAccessible()", function() {
   describe("#isAccessible()", function() {
     it("Upgrade running, element should be blocked", function() {
     it("Upgrade running, element should be blocked", function() {
-      App.set('isUpgrading', true);
+      App.set('upgradeState', "IN_PROGRESS");
       App.set('isAdmin', true);
       App.set('isAdmin', true);
       expect(App.isAccessible('ADMIN')).to.be.false;
       expect(App.isAccessible('ADMIN')).to.be.false;
     });
     });
     it("Upgrade running, upgrade element should not be blocked", function() {
     it("Upgrade running, upgrade element should not be blocked", function() {
-      App.set('isUpgrading', true);
+      App.set('upgradeState', "IN_PROGRESS");
       App.set('isAdmin', true);
       App.set('isAdmin', true);
       expect(App.isAccessible('upgrade_ADMIN')).to.be.true;
       expect(App.isAccessible('upgrade_ADMIN')).to.be.true;
     });
     });
     it("ADMIN type, isAdmin true", function() {
     it("ADMIN type, isAdmin true", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', true);
       App.set('isAdmin', true);
       expect(App.isAccessible('ADMIN')).to.be.true;
       expect(App.isAccessible('ADMIN')).to.be.true;
     });
     });
     it("ADMIN type, isAdmin false", function() {
     it("ADMIN type, isAdmin false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', false);
       App.set('isAdmin', false);
       expect(App.isAccessible('ADMIN')).to.be.false;
       expect(App.isAccessible('ADMIN')).to.be.false;
     });
     });
     it("MANAGER type, isOperator false", function() {
     it("MANAGER type, isOperator false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', true);
       App.set('isAdmin', true);
       App.set('isOperator', false);
       App.set('isOperator', false);
       expect(App.isAccessible('MANAGER')).to.be.true;
       expect(App.isAccessible('MANAGER')).to.be.true;
     });
     });
     it("MANAGER type, isAdmin false", function() {
     it("MANAGER type, isAdmin false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', false);
       App.set('isAdmin', false);
       App.set('isOperator', true);
       App.set('isOperator', true);
       expect(App.isAccessible('MANAGER')).to.be.true;
       expect(App.isAccessible('MANAGER')).to.be.true;
     });
     });
     it("MANAGER type, isAdmin and isOperator false", function() {
     it("MANAGER type, isAdmin and isOperator false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', false);
       App.set('isAdmin', false);
       App.set('isOperator', false);
       App.set('isOperator', false);
       expect(App.isAccessible('MANAGER')).to.be.false;
       expect(App.isAccessible('MANAGER')).to.be.false;
     });
     });
     it("OPERATOR type, isOperator false", function() {
     it("OPERATOR type, isOperator false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isOperator', false);
       App.set('isOperator', false);
       expect(App.isAccessible('OPERATOR')).to.be.false;
       expect(App.isAccessible('OPERATOR')).to.be.false;
     });
     });
     it("OPERATOR type, isOperator false", function() {
     it("OPERATOR type, isOperator false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isOperator', true);
       App.set('isOperator', true);
       expect(App.isAccessible('OPERATOR')).to.be.true;
       expect(App.isAccessible('OPERATOR')).to.be.true;
     });
     });
     it("ONLY_ADMIN type, isAdmin false", function() {
     it("ONLY_ADMIN type, isAdmin false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', false);
       App.set('isAdmin', false);
       expect(App.isAccessible('ONLY_ADMIN')).to.be.false;
       expect(App.isAccessible('ONLY_ADMIN')).to.be.false;
     });
     });
     it("ONLY_ADMIN type, isAdmin true, isOperator false", function() {
     it("ONLY_ADMIN type, isAdmin true, isOperator false", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', true);
       App.set('isAdmin', true);
       App.set('isOperator', false);
       App.set('isOperator', false);
       expect(App.isAccessible('ONLY_ADMIN')).to.be.true;
       expect(App.isAccessible('ONLY_ADMIN')).to.be.true;
     });
     });
     it("ONLY_ADMIN type, isAdmin true, isOperator true", function() {
     it("ONLY_ADMIN type, isAdmin true, isOperator true", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       App.set('isAdmin', true);
       App.set('isAdmin', true);
       App.set('isOperator', true);
       App.set('isOperator', true);
       expect(App.isAccessible('ONLY_ADMIN')).to.be.false;
       expect(App.isAccessible('ONLY_ADMIN')).to.be.false;
     });
     });
     it("unknown type", function() {
     it("unknown type", function() {
-      App.set('isUpgrading', false);
+      App.set('upgradeState', "INIT");
       expect(App.isAccessible('')).to.be.false;
       expect(App.isAccessible('')).to.be.false;
     });
     });
   });
   });

+ 101 - 17
ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js

@@ -83,17 +83,31 @@ describe('App.MainAdminStackAndUpgradeController', function() {
   });
   });
 
 
   describe("#loadVersionsInfoSuccessCallback()", function() {
   describe("#loadVersionsInfoSuccessCallback()", function() {
-    it("", function() {
+    it("target version installed and higher than current", function() {
       var data = {"items": [
       var data = {"items": [
         {
         {
           "ClusterStackVersions": {
           "ClusterStackVersions": {
             "state": "CURRENT"
             "state": "CURRENT"
-          }
+          },
+          "repository_versions": [
+            {
+              "RepositoryVersions" : {
+                "repository_version" : "2.2.0.1-885"
+              }
+            }
+          ]
         },
         },
         {
         {
           "ClusterStackVersions": {
           "ClusterStackVersions": {
             "state": "INSTALLED"
             "state": "INSTALLED"
-          }
+          },
+          "repository_versions": [
+            {
+              "RepositoryVersions" : {
+                "repository_version" : "2.2.1.1-885"
+              }
+            }
+          ]
         }
         }
       ]};
       ]};
       controller.loadVersionsInfoSuccessCallback(data);
       controller.loadVersionsInfoSuccessCallback(data);
@@ -104,9 +118,75 @@ describe('App.MainAdminStackAndUpgradeController', function() {
         "state": "INSTALLED"
         "state": "INSTALLED"
       }]);
       }]);
     });
     });
+    it("target version installed and lower than current", function() {
+      var data = {"items": [
+        {
+          "ClusterStackVersions": {
+            "state": "CURRENT"
+          },
+          "repository_versions": [
+            {
+              "RepositoryVersions" : {
+                "repository_version" : "2.2.0.1-885"
+              }
+            }
+          ]
+        },
+        {
+          "ClusterStackVersions": {
+            "state": "INSTALLED"
+          },
+          "repository_versions": [
+            {
+              "RepositoryVersions" : {
+                "repository_version" : "2.2.0.1-885"
+              }
+            }
+          ]
+        }
+      ]};
+      controller.loadVersionsInfoSuccessCallback(data);
+      expect(controller.get('currentVersion')).to.eql({
+        "state": "CURRENT"
+      });
+      expect(controller.get('targetVersions')).to.be.empty;
+    });
+    it("target version not installed and lower than current", function() {
+      var data = {"items": [
+        {
+          "ClusterStackVersions": {
+            "state": "CURRENT"
+          },
+          "repository_versions": [
+            {
+              "RepositoryVersions" : {
+                "repository_version" : "2.2.0.1-885"
+              }
+            }
+          ]
+        },
+        {
+          "ClusterStackVersions": {
+            "state": "INIT"
+          },
+          "repository_versions": [
+            {
+              "RepositoryVersions" : {
+                "repository_version" : "2.2.0.1-885"
+              }
+            }
+          ]
+        }
+      ]};
+      controller.loadVersionsInfoSuccessCallback(data);
+      expect(controller.get('currentVersion')).to.eql({
+        "state": "CURRENT"
+      });
+      expect(controller.get('targetVersions')).to.be.empty;
+    });
   });
   });
 
 
-  describe("#loadUpgradeTasks()", function() {
+  describe("#loadUpgradeData()", function() {
     before(function () {
     before(function () {
       sinon.stub(App.ajax, 'send', Em.K);
       sinon.stub(App.ajax, 'send', Em.K);
     });
     });
@@ -114,31 +194,35 @@ describe('App.MainAdminStackAndUpgradeController', function() {
       App.ajax.send.restore();
       App.ajax.send.restore();
     });
     });
     it("make ajax call", function() {
     it("make ajax call", function() {
-      controller.loadUpgradeTasks();
+      controller.loadUpgradeData();
       expect(App.ajax.send.getCall(0).args[0]).to.eql({
       expect(App.ajax.send.getCall(0).args[0]).to.eql({
-        name: 'admin.upgrade.tasks',
+        name: 'admin.upgrade.data',
         sender: controller,
         sender: controller,
         data: {
         data: {
           id: 1
           id: 1
         },
         },
-        success: 'loadUpgradeTasksSuccessCallback'
+        success: 'loadUpgradeDataSuccessCallback'
       })
       })
     });
     });
   });
   });
 
 
-  describe("#loadUpgradeTasksSuccessCallback()", function() {
+  describe("#loadUpgradeDataSuccessCallback()", function() {
     it("", function() {
     it("", function() {
-      var data = {"items": [
+      var data = {"upgrade_groups": [
         {
         {
-          "UpgradeItem": {
+          "UpgradeGroup": {
             "id": 1
             "id": 1
-          }
+          },
+          "upgrade_items": []
         }
         }
       ]};
       ]};
-      controller.loadUpgradeTasksSuccessCallback(data);
-      expect(controller.get('upgradeTasks')).to.eql([
+      controller.loadUpgradeDataSuccessCallback(data);
+      expect(controller.get('upgradeGroups')).to.eql([
         {
         {
-          "id": 1
+          "UpgradeGroup": {
+            "id": 1
+          },
+          "upgrade_items": []
         }
         }
       ]);
       ]);
     });
     });
@@ -146,14 +230,14 @@ describe('App.MainAdminStackAndUpgradeController', function() {
 
 
   describe("#openUpgradeDialog()", function () {
   describe("#openUpgradeDialog()", function () {
     before(function () {
     before(function () {
-      sinon.stub(App.ModalPopup, 'show', Em.K);
+      sinon.stub(App.router, 'transitionTo', Em.K);
     });
     });
     after(function () {
     after(function () {
-      App.ModalPopup.show.restore();
+      App.router.transitionTo.restore();
     });
     });
     it("should open dialog", function () {
     it("should open dialog", function () {
       controller.openUpgradeDialog();
       controller.openUpgradeDialog();
-      expect(App.ModalPopup.show.calledOnce).to.be.true;
+      expect(App.router.transitionTo.calledWith('admin.stackUpgrade')).to.be.true;
     });
     });
   });
   });
 });
 });

+ 7 - 5
ambari-web/test/views/main/admin/stack_upgrade/upgrade_task_view_test.js

@@ -22,7 +22,9 @@ require('views/main/admin/stack_upgrade/upgrade_task_view');
 
 
 describe('App.upgradeTaskView', function () {
 describe('App.upgradeTaskView', function () {
   var view = App.upgradeTaskView.create({
   var view = App.upgradeTaskView.create({
-    content: Em.Object.create()
+    content: Em.Object.create({
+      UpgradeGroup: {}
+    })
   });
   });
 
 
   describe("#iconClass", function () {
   describe("#iconClass", function () {
@@ -30,7 +32,7 @@ describe('App.upgradeTaskView', function () {
       view.set('statusIconMap', {
       view.set('statusIconMap', {
         'S1': 'icon1'
         'S1': 'icon1'
       });
       });
-      view.set('content.status', 'S1');
+      view.set('content.UpgradeGroup.state', 'S1');
       view.propertyDidChange('iconClass');
       view.propertyDidChange('iconClass');
       expect(view.get('iconClass')).to.equal('icon1');
       expect(view.get('iconClass')).to.equal('icon1');
     });
     });
@@ -38,7 +40,7 @@ describe('App.upgradeTaskView', function () {
       view.set('statusIconMap', {
       view.set('statusIconMap', {
         'S1': 'icon1'
         'S1': 'icon1'
       });
       });
-      view.set('content.status', 'S2');
+      view.set('content.UpgradeGroup.state', 'S2');
       view.propertyDidChange('iconClass');
       view.propertyDidChange('iconClass');
       expect(view.get('iconClass')).to.equal('icon-question-sign');
       expect(view.get('iconClass')).to.equal('icon-question-sign');
     });
     });
@@ -46,12 +48,12 @@ describe('App.upgradeTaskView', function () {
 
 
   describe("#isFailed", function () {
   describe("#isFailed", function () {
     it("task is not failed", function () {
     it("task is not failed", function () {
-      view.set('content.status', 'COMPLETED');
+      view.set('content.UpgradeGroup.state', 'COMPLETED');
       view.propertyDidChange('isFailed');
       view.propertyDidChange('isFailed');
       expect(view.get('isFailed')).to.be.false;
       expect(view.get('isFailed')).to.be.false;
     });
     });
     it("task is not failed", function () {
     it("task is not failed", function () {
-      view.set('content.status', 'FAILED');
+      view.set('content.UpgradeGroup.state', 'FAILED');
       view.propertyDidChange('isFailed');
       view.propertyDidChange('isFailed');
       expect(view.get('isFailed')).to.be.true;
       expect(view.get('isFailed')).to.be.true;
     });
     });