Преглед изворни кода

AMBARI-8529 e2e integration for stack versions. (ababiichuk)

aBabiichuk пре 10 година
родитељ
комит
bc8c329376

+ 76 - 143
ambari-web/app/assets/data/stack_versions/stack_version_all.json

@@ -1,149 +1,82 @@
 {
-  "items": [
+  "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions?fields=*,repository_versions/*,repository_versions/operatingSystems/repositories/*&_=1417611809864",
+  "items" : [
     {
-      "ClusterStackVersions": {
-        "state": "CURRENT",
-        "stack": "HDP",
-        "version": "2.2.0.1-885",
-        "installed_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com"],
-        "current_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com"],
-        "repositories": [
-          {
-            "os": "redhat6",
-            "baseurls": [
-              {
-                "id": "HDP-2.2.0.1-885",
-                "type": "HDP",
-                "baseurl": "http://dev01.hortonworks.com/hdp"
-              },
-              {
-                "id": "HDP-UTILS-1.0.0.20",
-                "type": "HDP-UTILS",
-                "baseurl": "http://dev01.hortonworks.com/hdp-utils"
-              }
-            ]
-          }
-        ]
-      }
-    },
-    {
-      "ClusterStackVersions": {
-        "state": "INSTALLED",
-        "stack": "HDP",
-        "version": "2.2.1.1-885",
-        "installed_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com"],
-        "current_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com"],
-        "repositories": [
-          {
-            "os": "redhat6",
-            "baseurls": [
-              {
-                "id": "HDP-2.2.0.1-885",
-                "type": "HDP",
-                "baseurl": "http://dev01.hortonworks.com/hdp"
-              },
-              {
-                "id": "HDP-UTILS-1.0.0.20",
-                "type": "HDP-UTILS",
-                "baseurl": "http://dev01.hortonworks.com/hdp-utils"
-              }
-            ]
-          }
-        ]
-      }
-    },
-    {
-      "ClusterStackVersions": {
-        "state": "INSTALLED",
-        "stack": "HDP",
-        "version": "2.2.2.1-885",
-        "installed_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com"],
-        "current_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com"],
-        "repositories": [
-          {
-            "os": "redhat6",
-            "baseurls": [
-              {
-                "id": "HDP-2.2.0.1-885",
-                "type": "HDP",
-                "baseurl": "http://dev01.hortonworks.com/hdp"
-              },
-              {
-                "id": "HDP-UTILS-1.0.0.20",
-                "type": "HDP-UTILS",
-                "baseurl": "http://dev01.hortonworks.com/hdp-utils"
-              }
-            ]
+      "href" : "http://162.216.148.202:8080/api/v1/clusters/1/stack_versions/2",
+      "ClusterStackVersions" : {
+        "cluster_name" : "1",
+        "id" : 2,
+        "stack" : "HDP",
+        "state" : "CURRENT",
+        "version" : "2.2",
+        "host_states" : {
+          "CURRENT" : [
+            "ab3test-2.c.pramod-thangali.internal"
+          ],
+          "INSTALLED" : [ ],
+          "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.1",
+            "id" : 1,
+            "repository_version" : "2.2.1.1-885",
+            "stack_name" : "HDP",
+            "stack_version" : "2.2",
+            "upgrade_pack" : "upgrade-2.2"
           },
-          {
-            "os": "ubuntu12",
-            "baseurls": [
-              {
-                "id": "HDP-2.2.0.1-885",
-                "type": "HDP",
-                "baseurl": "http://dev01.hortonworks.com/hdp"
-              },
-              {
-                "id": "HDP-UTILS-1.0.0.20",
-                "type": "HDP-UTILS",
-                "baseurl": "http://dev01.hortonworks.com/hdp-utils"
-              }
-            ]
-          }
-        ]
-      }
-    },
-    {
-      "ClusterStackVersions": {
-        "state": "INSTALLED",
-        "stack": "HDP",
-        "version": "2.3.0.1-885",
-        "installed_hosts": [],
-        "current_hosts": [],
-        "repositories": [
-          {
-            "os": "redhat6",
-            "baseurls": [
-              {
-                "id": "HDP-2.2.0.1-885",
-                "type": "HDP",
-                "baseurl": "http://dev01.hortonworks.com/hdp"
-              },
-              {
-                "id": "HDP-UTILS-1.0.0.20",
-                "type": "HDP-UTILS",
-                "baseurl": "http://dev01.hortonworks.com/hdp-utils"
-              }
-            ]
-          }
-        ]
-      }
-    },
-    {
-      "ClusterStackVersions": {
-        "state": "INSTALLED",
-        "stack": "HDP",
-        "version": "2.2.0.3",
-        "installed_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com", "dev03.hortonworks.com"],
-        "current_hosts": ["dev01.hortonworks.com", "dev02.hortonworks.com", "dev03.hortonworks.com"],
-        "repositories": [
-          {
-            "os": "redhat6",
-            "baseurls": [
-              {
-                "id": "HDP-2.2.0.1-885",
-                "type": "HDP",
-                "baseurl": "http://dev01.hortonworks.com/hdp"
+          "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" : 1,
+                "stack_name" : "HDP",
+                "stack_version" : "2.2"
               },
-              {
-                "id": "HDP-UTILS-1.0.0.20",
-                "type": "HDP-UTILS",
-                "baseurl": "http://dev01.hortonworks.com/hdp-utils"
-              }
-            ]
-          }
-        ]
-      }
+              "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" : 1,
+                    "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" : 1,
+                    "stack_name" : "HDP",
+                    "stack_version" : "2.2"
+                  }
+                }
+              ]
+            }
+          ]
+        }
+      ]
     }
   ]
-}
+}

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

@@ -27,21 +27,47 @@ App.MainStackVersionsDetailsController = Em.Controller.extend({
     return App.get('allHostNames.length');
   }.property('App.allHostNames.length'),
 
+
+  notInstalledHostsCount: function() {
+    return this.get('content.state') == 'INIT' ? this.get('totalHostCount.length') : 0;
+  }.property('content.state', 'totalHostCount.length'),
+
+  noInitHosts: function() {
+    return this.get('notInstalledHostsCount.length') == 0;
+  }.property('notInstalledHostsCount.length'),
   /**
-   * true if install stack version is in progress at least on 1 host
+   * true if stack version install is in progress
    * {Boolean}
    */
   installInProgress: function() {
-    return this.get('content.upgradingHostStacks.length');
-  }.property('content.upgradingHostStacks.length'),
+    return this.get('content.state') == "INSTALLING";
+  }.property('content.state'),
+
+  /**
+   * true if stack version upgrade is in progress
+   * {Boolean}
+   */
+  upgradeInProgress: function() {
+    return this.get('content.state') == "UPGRADING";
+  }.property('content.state'),
 
   /**
-   * true if repo version is installed on all hosts
+   * true if repo version is installed on all hosts but not upgraded
    * {Boolean}
    */
+  installedNotUpgraded: function() {
+    return this.get("allInstalled") && !this.get("allUpgraded") ;
+  }.property("allInstalled", "allUpgraded"),
+
   allInstalled: function() {
-    return this.get('content.notInstalledHostStacks.length') == 0;
-  }.property('content.notInstalledHostStacks.length'),
+    return this.get('content.installedHosts.length') == this.get('totalHostCount') ||
+      this.get('content.currentHosts.length') == this.get('totalHostCount');
+  }.property('content.installedHosts.length', 'content.currentHosts.length'),
+
+  allUpgraded: function() {
+    return this.get('content.upgradedHosts.length') == this.get('totalHostCount') ||
+      this.get('content.currentHosts.length') == this.get('totalHostCount');
+  }.property('content.upgradedHosts.length', 'content.currentHosts.length'),
 
   /**
    * depending on state run or install repo request
@@ -62,7 +88,7 @@ App.MainStackVersionsDetailsController = Em.Controller.extend({
    * @method showProgressPopup
    */
   showProgressPopup: function() {
-    var popupTitle = Em.I18n.t('admin.stackVersions.datails.install.hosts.popup.title').format(this.get('content.version'));
+    var popupTitle = Em.I18n.t('admin.stackVersions.datails.install.hosts.popup.title').format(this.get('content.repositoryVersion.displayName'));
     var requestIds = App.get('testMode') ? [1] : App.db.get('stackUpgrade', 'id');
     var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
     hostProgressPopupController.initPopup(popupTitle, requestIds, this, true);
@@ -75,59 +101,13 @@ App.MainStackVersionsDetailsController = Em.Controller.extend({
    * @method doInstallStackVersion
    */
   doInstallStackVersion: function(stackVersion) {
-    var services = App.Service.find();
-    var data = this.generateDataForInstall(stackVersion, services);
-    return App.ajax.send({
+    //TODO add correct request
+    return null;
+    /*return App.ajax.send({
       name: 'admin.stack_version.install.repo_version',
       data: data,
       success: 'installStackVersionSuccess'
-    })
-  },
-
-  /**
-   * generates the request data for installing repoversions
-   * @param {Ember.object} stackVersion
-   * @param {Array} services - array of service objects
-   * @returns {JSON}
-   * {
-   *  RequestInfo:
-   *   {
-   *     context: string,
-   *     action: string,
-   *     parameters:
-   *       {
-   *         name: string,
-   *         name_list: string,
-   *         base_url_list: string,
-   *         packages: string
-   *       }
-   *    },
-   *  Requests/resource_filters: [{hosts:string}]
-   * }
-   */
-  generateDataForInstall: function(stackVersion, services) {
-    var hostNames = stackVersion.get('hostStackVersions').mapProperty('host.hostName');
-    var base_urls = stackVersion.get('operatingSystems').map(function(os) {
-      return os.get('repositories').mapProperty('baseurl').join(",");
-    });
-    var serviceNames = services.mapProperty('serviceName');
-    return {
-      "RequestInfo": {
-        "context":"Install Repo Version" + stackVersion.get('version'),
-        "action":"ru_install_repo",
-        "parameters": {
-          "name": stackVersion.get('version'),
-          "name_list": stackVersion.get('name'),
-          "base_url_list": base_urls.join(","),
-          "packages": serviceNames.join(",")
-        }
-      },
-      "Requests/resource_filters": [
-        {
-          "hosts": hostNames.join(",")
-        }
-      ]
-    };
+    })*/
   },
 
   installStackVersionSuccess: function(data) {

+ 27 - 5
ambari-web/app/controllers/main/admin/stack_versions/stack_versions_controller.js

@@ -22,11 +22,32 @@ App.MainStackVersionsController = Em.ArrayController.extend({
   name: 'mainStackVersionsController',
 
   content: App.StackVersion.find(),
+  timeoutRef: null,
+  isPolling: false,
+  dataIsLoaded: false,
   mockUrl: '/data/stack_versions/stack_version_all.json',
   realUrl: function () {
-    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions&minimal_response=true';
+    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=*,repository_versions/*,repository_versions/operatingSystems/repositories/*';
+  }.property('App.clusterName'),
+  realUpdateUrl: function () {
+    return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=*,repository_versions/*,repository_versions/operatingSystems/repositories/*';
+    //TODO return App.apiPrefix + '/clusters/' + App.get('clusterName') + '/stack_versions?fields=ClusterStackVersions/state,ClusterStackVersions/host_states&minimal_response=true';
   }.property('App.clusterName'),
 
+  /**
+   * request latest data from server and update content
+   */
+  doPolling: function () {
+    var self = this;
+
+    this.set('timeoutRef', setTimeout(function () {
+      if (self.get('isPolling')) {
+        self.loadStackVersionsToModel(self.get('dataIsLoaded')).done(function () {
+          self.doPolling();
+        })
+      }
+    }, App.componentsUpdateInterval));
+  },
   /**
    * load all data components required by stack version table
    * @return {*}
@@ -45,10 +66,10 @@ App.MainStackVersionsController = Em.ArrayController.extend({
    * get stack versions from server and push it to model
    * @return {*}
    */
-  loadStackVersionsToModel: function () {
+  loadStackVersionsToModel: function (isUpdate) {
     var dfd = $.Deferred();
 
-    App.HttpClient.get(this.getUrl(), App.stackVersionMapper, {
+    App.HttpClient.get(this.getUrl(isUpdate), App.stackVersionMapper, {
       complete: function () {
         dfd.resolve();
       }
@@ -56,8 +77,9 @@ App.MainStackVersionsController = Em.ArrayController.extend({
     return dfd.promise();
   },
 
-  getUrl: function () {
-    return App.get('testMode') ? this.get('mockUrl') : this.get('realUrl');
+  getUrl: function (isUpdate) {
+    return App.get('testMode') ? this.get('mockUrl') :
+      isUpdate ? this.get('realUpdateUrl') : this.get('realUrl');
   },
 
   filterHostsByStack: function (version, state) {

+ 1 - 0
ambari-web/app/mappers.js

@@ -21,6 +21,7 @@ require('mappers/server_data_mapper');
 require('mappers/stack_service_mapper');
 require('mappers/stack_mapper');
 require('mappers/stack_version_mapper');
+require('mappers/repository_version_mapper');
 require('mappers/hosts_mapper');
 require('mappers/jobs_mapper');
 require('mappers/cluster_mapper');

+ 108 - 0
ambari-web/app/mappers/repository_version_mapper.js

@@ -0,0 +1,108 @@
+/**
+ * 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');
+
+App.repoVersionMapper = App.QuickDataMapper.create({
+  modelRepoVersions: App.RepositoryVersion,
+  modelOperatingSystems: App.OS,
+  modelRepositories: App.Repository,
+
+  modelRepoVersion: {
+    id: 'RepositoryVersions.id',
+    stack_version_id: 'RepositoryVersions.stackVersionId',
+    display_name: 'RepositoryVersions.display_name',
+    repository_version: 'RepositoryVersions.repository_version',
+    upgrade_pack: 'RepositoryVersions.upgrade_pack',
+    stack_version_type: 'RepositoryVersions.stack_name',
+    stack_version_number: 'RepositoryVersions.stack_version',
+    operating_systems_key: 'operating_systems',
+    operating_systems_type: 'array',
+    operating_systems: {
+      item: 'id'
+    }
+  },
+
+  modelOS: {
+    id: 'id',
+    repository_version_id: 'repository_version_id',
+    os_type: 'OperatingSystems.os_type',
+    stack_name: 'OperatingSystems.stack_name',
+    stack_version: 'OperatingSystems.stack_version',
+    repositories_key: 'repositories',
+    repositories_type: 'array',
+    repositories: {
+      item: 'id'
+    }
+  },
+
+  modelRepository: {
+    id: 'id',
+    operating_system_id: 'Repositories.operating_system_id',
+    base_url : 'Repositories.base_url',
+    default_base_url : 'Repositories.default_base_url',
+    latest_base_url : 'Repositories.latest_base_url',
+    mirrors_list : 'Repositories.mirrors_list',
+    os_type : 'Repositories.os_type',
+    repo_id : 'Repositories.repo_id',
+    repo_name : 'Repositories.repo_name',
+    stack_name : 'Repositories.stack_name',
+    stack_version : 'Repositories.stack_version'
+  },
+
+  map: function (json) {
+    var modelRepoVersions = this.get('modelRepoVersions');
+    var modelOperatingSystems = this.get('modelOperatingSystems');
+    var modelRepositories = this.get('modelRepositories');
+
+    var resultRepoVersion = [];
+    var resultOS = [];
+    var resultRepo = [];
+
+    if (json && json.items) {
+      json.items.forEach(function (item) {
+        var repo = item;
+        var osArray = [];
+
+        if (Em.get(item, 'operating_systems')) {
+          item.operating_systems.forEach(function (os) {
+            os.id = item.RepositoryVersions.repository_version + os.OperatingSystems.os_type;
+            os.repository_version_id = repo.id;
+            var repoArray = [];
+            if (Em.get(os, 'repositories')) {
+              os.repositories.forEach(function(repo) {
+                repo.id = repo.Repositories.repo_id + os.id;
+                repo.operating_system_id = os.id;
+                repoArray.pushObject(repo);
+                resultRepo.push(this.parseIt(repo, this.get('modelRepository')));
+              }, this);
+            }
+            os.repositories = repoArray;
+            osArray.pushObject(os);
+            resultOS.push(this.parseIt(os, this.get('modelOS')));
+          }, this);
+        }
+        repo.operating_systems = osArray;
+        resultRepoVersion.push(this.parseIt(repo, this.get('modelRepoVersion')));
+      }, this);
+    }
+    App.store.commit();
+    App.store.loadMany(modelRepositories, resultRepo);
+    App.store.loadMany(modelOperatingSystems, resultOS);
+    App.store.loadMany(modelRepoVersions, resultRepoVersion);
+  }
+});

+ 19 - 73
ambari-web/app/mappers/stack_version_mapper.js

@@ -19,93 +19,39 @@ var App = require('app');
 
 App.stackVersionMapper = App.QuickDataMapper.create({
   modelStackVerion: App.StackVersion,
-  modelRepositories: App.Repositories,
-  modelOperatingSystems: App.OS,
 
   modelStack: {
-    id: 'id',
-    name: 'name',
-    version: 'version',
-    operating_systems_key: 'operating_systems',
-    operating_systems_type: 'array',
-    operating_systems: {
-      item: 'id'
-    },
-    host_stack_versions_key: 'host_stack_versions',
-    host_stack_versions_type: 'array',
-    host_stack_versions: {
-      item: 'id'
-    },
-    installed_hosts: 'installed_hosts',
-    current_hosts: 'current_hosts'
-  },
-
-  modelOS: {
-    id: 'id',
-    name: 'os',
-    stack_version_id: 'stack_version_id',
-    repositories_key: 'repositories',
-    repositories_type: 'array',
-    repositories: {
-      item: 'id'
-    }
-  },
-
-  modelRepository: {
-    id: 'id',
-    type: 'type',
-    baseurl: 'baseurl',
-    os_id: 'os_id'
+    "id": "id",
+    "cluster_name": "cluster_name",
+    "stack": "stack",
+    "version": "version",
+    "repository_version_id": "repository_version_id",
+    "state": "state",
+    "installing_hosts": "host_states.INSTALLING",
+    "installed_hosts": "host_states.INSTALLED",
+    "install_failed_hosts": "host_states.INSTALL_FAILED",
+    "upgrading_hosts": "host_states.UPGRADING",
+    "upgraded_hosts": "host_states.UPGRADED",
+    "upgrade_failed_hosts": "host_states.UPGRADE_FAILED",
+    "current_hosts": "host_states.CURRENT"
   },
 
   map: function (json) {
     var modelStackVerion = this.get('modelStackVerion');
-    var modelOperatingSystems = this.get('modelOperatingSystems');
-    var modelRepositories = this.get('modelRepositories');
-
     var resultStack = [];
-    var resultOS = [];
-    var resultRepo = [];
 
     if (json && json.items) {
       json.items.forEach(function (item) {
-        var stack = item.StackVersion;
-        stack.id = item.StackVersion.name + item.StackVersion.version;
-        var osArray = [];
-        var hostStackVersions = [];
-
-        if (Em.get(item, 'StackVersion.repositories')) {
-          item.StackVersion.repositories.forEach(function (os) {
-            os.id = item.StackVersion.version + os.os;
-            os.stack_version_id = stack.id;
-            os.name = os.os;
-            var repoArray = [];
-
-            if (Em.get(os, 'baseurls')) {
-              os.baseurls.forEach(function (repo) {
-                repo.os_id = os.id;
-                resultRepo.push(this.parseIt(repo, this.get('modelRepository')));
-                repoArray.pushObject(repo);
-              }, this);
-            }
-
-            os.repositories = repoArray;
-            resultOS.push(this.parseIt(os, this.get('modelOS')));
-            osArray.pushObject(os);
-          }, this);
+        var stack = item.ClusterStackVersions;
+        if (item.repository_versions[0]) {
+          stack.repository_version_id = item.repository_versions[0].RepositoryVersions.id;
+          item.repository_versions[0].RepositoryVersions.stackVersionId = item.ClusterStackVersions.id;
+          resultStack.push(this.parseIt(stack, this.get('modelStack')));
+          App.repoVersionMapper.map({"items": item.repository_versions });
         }
-        //TODO change loading form current api
-        App.HostStackVersion.find().filterProperty('version', item.StackVersion.version).forEach(function(hv) {
-          hostStackVersions.push({id: hv.get('id')});
-        });
-        stack.host_stack_versions = hostStackVersions;
-        stack.operating_systems = osArray;
-        resultStack.push(this.parseIt(stack, this.get('modelStack')));
       }, this);
     }
     App.store.commit();
-    App.store.loadMany(modelRepositories, resultRepo);
-    App.store.loadMany(modelOperatingSystems, resultOS);
     App.store.loadMany(modelStackVerion, resultStack);
   }
 });

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

@@ -1249,11 +1249,13 @@ Em.I18n.translations = {
   'admin.stackVersions.datails.versionName': "Version Name",
   'admin.stackVersions.datails.installed.on': "Installed On",
   'admin.stackVersions.datails.current.on': "Current On",
+  'admin.stackVersions.datails.not.installed.on': "Not installed on",
   'admin.stackVersions.datails.base.url': "Base Url",
 
   'admin.stackVersions.datails.hosts.btn.install': "Install to {0} hosts",
   'admin.stackVersions.datails.hosts.btn.installing': "Installing...",
-  'admin.stackVersions.datails.hosts.btn.nothing': "Nothing to Install",
+  'admin.stackVersions.datails.hosts.btn.nothing': "Installed on all hosts",
+  'admin.stackVersions.datails.hosts.btn.goto.upgrade': "Proceed to upgrade",
   'admin.stackVersions.datails.hosts.btn.na': "Status not available",
   'admin.stackVersions.datails.install.hosts.popup.title': "Install {0} version",
 

+ 1 - 0
ambari-web/app/models.js

@@ -26,6 +26,7 @@ require('models/cluster_states');
 require('models/hosts');
 require('models/stack');
 require('models/stack_version/version');
+require('models/stack_version/repository_version');
 require('models/stack_version/os');
 require('models/stack_version/repository');
 require('models/operating_system');

+ 5 - 3
ambari-web/app/models/stack_version/os.js

@@ -20,9 +20,11 @@ var App = require('app');
 
 App.OS = DS.Model.extend({
   id: DS.attr('string'),
-  name: DS.attr('string'),
-  stackVersion: DS.belongsTo('App.StackVersion'),
-  repositories: DS.hasMany('App.Repositories')
+  osType : DS.attr('string'),
+  stackName : DS.attr('string'),
+  stackVersion : DS.attr('string'),
+  repositoryVersion: DS.belongsTo('App.RepositoryVersion'),
+  repositories: DS.hasMany('App.Repository')
 });
 
 App.OS.FIXTURES = [];

+ 12 - 5
ambari-web/app/models/stack_version/repository.js

@@ -18,13 +18,20 @@
 
 var App = require('app');
 
-App.Repositories = DS.Model.extend({
+App.Repository = DS.Model.extend({
   id: DS.attr('string'),
-  type: DS.attr('string'),
-  baseurl: DS.attr('string'),
-  os: DS.belongsTo('App.OS')
+  baseUrl : DS.attr('string'),
+  defaultBaseUrl : DS.attr('string'),
+  latestBaseUrl : DS.attr('string'),
+  mirrorsList : DS.attr('array'),
+  osType : DS.attr('string'),
+  repoId : DS.attr('string'),
+  repoName : DS.attr('string'),
+  stackName : DS.attr('string'),
+  stackVersion : DS.attr('string'),
+  operatingSystem: DS.belongsTo('App.OS')
 });
 
-App.Repositories.FIXTURES = [];
+App.Repository.FIXTURES = [];
 
 

+ 36 - 0
ambari-web/app/models/stack_version/repository_version.js

@@ -0,0 +1,36 @@
+/**
+ * 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');
+
+App.RepositoryVersion = DS.Model.extend({
+  id: DS.attr('string'),
+  displayName : DS.attr('string'),
+  repositoryVersion : DS.attr('string'),
+  upgradePack : DS.attr('string'),
+  stackVersionType : DS.attr('string'),
+  stackVersionNumber : DS.attr('string'),
+  operatingSystems: DS.hasMany('App.OS'),
+  stackVersion: DS.belongsTo('App.StackVersion'),
+  stack: function() {
+    return this.get('stackVersionType') + " " + this.get('stackVersionNumber');
+  }.property('stackVersionType', 'stackVersionNumber')
+});
+
+App.RepositoryVersion.FIXTURES = [];
+

+ 12 - 54
ambari-web/app/models/stack_version/version.js

@@ -20,63 +20,21 @@ var App = require('app');
 
 App.StackVersion = DS.Model.extend({
   id: DS.attr('string'),
-  name: DS.attr('string'),
+  clusterName: DS.attr('string'),
+  stack: DS.attr('string'),
   version: DS.attr('string'),
+  name: function() {
+    return this.get('stack') + " " + this.get('version');
+  }.property('stack', 'version'),
+  state: DS.attr('string'),
+  repositoryVersion: DS.belongsTo('App.RepositoryVersion'),
+  installingHosts: DS.attr('array'),
   installedHosts: DS.attr('array'),
+  installFailedHosts: DS.attr('array'),
+  upgradingHosts: DS.attr('array'),
+  upgradedHosts: DS.attr('array'),
+  upgradeFailedHosts: DS.attr('array'),
   currentHosts: DS.attr('array'),
-  operatingSystems: DS.hasMany('App.OS'),
-  hostStackVersions: DS.hasMany('App.HostStackVersion'),
-
-  setStatusHosts: function(){
-    Em.run.once(this, 'updateStatus');
-  }.observes('hostStackVersions.@each.status'),
-
-  updateStatus: function() {
-    var current = [];
-    var installed = [];
-    var upgradeFailed = [];
-    var upgrading = [];
-    var init = [];
-    var notInstalled = [];
-    this.get('hostStackVersions').forEach(function(hv) {
-      switch(hv.get('status')) {
-        case 'CURRENT':
-          current.push(hv);
-        case 'INSTALLED':
-          installed.push(hv);
-          break;
-        case 'INIT':
-          init.push(hv);
-          notInstalled.push(hv);
-          break;
-        case 'UPGRADE_FAILED':
-          upgradeFailed.push(hv);
-          notInstalled.push(hv);
-          break;
-        case 'UPGRADING':
-          upgrading.push(hv);
-          break;
-      }
-    });
-    this.set('currentHostStacks', current);
-    this.set('installedHostStacks', installed);
-    this.set('notInstalledHostStacks', notInstalled);
-    this.set('upgradeFailedHostStacks', upgradeFailed);
-    this.set('initHostStacks', init);
-    this.set('upgradingHostStacks', upgrading);
-  },
-
-  currentHostStacks: [],
-
-  installedHostStacks: [],
-
-  upgradeFailedHostStacks: [],
-
-  upgradingHostStacks: [],
-
-  initHostStacks: [],
-
-  notInstalledHostStacks: [],
 
   noInstalledHosts:  function() {
     return this.get('installedHosts.length') == 0;

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

@@ -522,11 +522,6 @@ module.exports = Em.Route.extend({
     }),
     adminStackVersions: Em.Route.extend({
       route: '/versions',
-      connectOutlets: function (router) {
-        if (App.get('supports.stackUpgrade')) {
-          router.get('mainStackVersionsController').load();
-        }
-      },
       index: Em.Route.extend({
         route: '/',
         connectOutlets: function (router) {

+ 25 - 15
ambari-web/app/templates/main/admin/stack_versions/stack_version_details.hbs

@@ -17,7 +17,7 @@
 }}
 
 <div id="stack-version-details">
-  <a class="breadcrumbs" href="#/main/admin/versions">{{t common.versions}}</a><span>&nbsp; > &nbsp;{{content.name}}</span>
+  <a class="breadcrumbs" href="#/main/admin/versions">{{t common.versions}}</a><span>&nbsp; > &nbsp;{{content.repositoryVersion.displayName}}</span>
 
   <div class="box">
     <div class="box-header">
@@ -30,7 +30,7 @@
       </div>
       <div class="row-fluid">
         <div class="span3">{{t admin.stackVersions.datails.versionName}}</div>
-        <div class="span6">{{content.version}}</div>
+        <div class="span6">{{content.repositoryVersion.displayName}}</div>
       </div>
     </div>
   </div>
@@ -42,29 +42,39 @@
     <div class="version-content">
       <div class="row-fluid">
         <div class="span8">
+          <div class="row-fluid">
+            <div class="span3">{{t admin.stackVersions.datails.not.installed.on}}</div>
+            <div {{bindAttr class="noInitHosts:not-active-link :span6"}}>
+              <a href="#" title='current' class="not-installed-hosts-count"
+                {{action showHosts content.repositoryVersion.displayName content.notInstalledHosts target="App.router.mainStackVersionsController"}}>
+                {{notInstalledHostsCount}}/{{totalHostCount}}
+              </a>
+            </div>
+          </div>
           <div class="row-fluid">
             <div class="span3">{{t admin.stackVersions.datails.installed.on}}</div>
-            <div class="span6">
-              <a href="#" title='installed' {{bindAttr class="controller.content.noInstalledHosts:not-active-link :installed-hosts-count"}}
-                {{action showHosts controller.content.version controller.content.installedHosts target="App.router.mainStackVersionsController"}}>
-                <span>{{content.installedHosts.length}}/{{totalHostCount}}</span>
+            <div {{bindAttr class="content.noInstalledHosts:not-active-link :span6"}}>
+              <a href="#" title='installed' class="installed-hosts-count"
+                {{action showHosts content.repositoryVersion.displayName content.installedHosts target="App.router.mainStackVersionsController"}}>
+                {{content.installedHosts.length}}/{{totalHostCount}}
               </a>
             </div>
           </div>
           <div class="row-fluid">
             <div class="span3">{{t admin.stackVersions.datails.current.on}}</div>
-            <div class="span6">
-              <a href="#" title='current' {{bindAttr class="controller.content.noCurrentHosts:not-active-link :current-hosts-count"}}
-                {{action showHosts controller.content.version controller.content.currentHosts target="App.router.mainStackVersionsController"}}>
-                <span>{{content.currentHosts.length}}/{{totalHostCount}}</span>
+            <div {{bindAttr class="content.noCurrentHosts:not-active-link :span6"}}>
+              <a href="#" title='current' class="current-hosts-count"
+                {{action showHosts content.repositoryVersion.displayName content.currentHosts target="App.router.mainStackVersionsController"}}>
+                {{content.currentHosts.length}}/{{totalHostCount}}
               </a>
             </div>
           </div>
         </div>
-        <div class="span4">
+        <div class="span4 align-center">
           <a id="repo-version-action-button" {{bindAttr class="view.statusClass :btn :stack-status-button"}} {{action installStackVersion content target="controller"}}>
             <i {{bindAttr class="installInProgress:icon-cog"}}>&nbsp;</i>{{view.stackTextStatus}}
           </a>
+          <a href="#/main/admin/stack" {{bindAttr class="installedNotUpgraded::hidden"}} >{{t admin.stackVersions.datails.hosts.btn.goto.upgrade}}</a>
         </div>
       </div>
     </div>
@@ -90,17 +100,17 @@
         </tr>
         </thead>
         <tbody>
-        {{#each os in content.operatingSystems}}
+        {{#each os in content.repositoryVersion.operatingSystems}}
           {{#each repo in os.repositories}}
             <tr>
               <td>
-                {{os.name}}
+                {{os.osType}}
               </td>
               <td>
-                {{repo.type}}
+                {{repo.repoId}}
               </td>
               <td>
-                {{view Ember.TextField valueBinding="repo.baseurl" disabled="disabled"}}
+                {{view Ember.TextField valueBinding="repo.baseUrl" disabled="disabled"}}
               </td>
             </tr>
           {{/each}}

+ 6 - 6
ambari-web/app/templates/main/admin/stack_versions/stack_versions.hbs

@@ -23,7 +23,7 @@
       {{view view.parentView.stackNameSort}}
       {{view view.parentView.stackVersionSort}}
       {{view view.parentView.osSort}}
-      {{view view.parentView.istalledSort}}
+      {{view view.parentView.installedSort}}
       {{view view.parentView.currentSort}}
     {{/view}}
 
@@ -40,15 +40,15 @@
         {{#each item in view.pageContent}}
           {{#view view.StackVersionView contentBinding="item"}}
             <td class="first stack-name">
-              <a href="#/main/admin/versions/{{unbound view.content.id}}" class="stack-name">{{view.content.name}}</a>
+               <span class="stack-name">{{view.content.name}}</span>
             </td>
             <td class="repo-version">
-              <span>{{view.content.version}}</span>
+              <a href="#/main/admin/versions/{{unbound view.content.id}}">{{view.content.repositoryVersion.displayName}}</a>
             </td>
             <td class="os-types">
               <a href="#" class="os-expander" {{action toggleOs target="view"}}>
                 <span {{bindAttr class="view.isOsCollapsed:icon-caret-right:icon-caret-down"}}></span>
-                {{view.content.operatingSystems.length}} {{pluralize view.content.operatingSystems.length singular="t:common.os" plural="t:common.oss"}}
+                {{view.content.repositoryVersion.operatingSystems.length}} {{pluralize view.content.repositoryVersion.operatingSystems.length singular="t:common.os" plural="t:common.oss"}}
               </a>
 
               <div id="stack-{{view.content.name}}" class="operating-systems">
@@ -58,7 +58,7 @@
             <td class="installed-hosts-count">
               <span  {{bindAttr class="view.content.noInstalledHosts:not-active-link"}}>
                 <a href="#"
-                  title='installed' {{action showHosts view.content.version view.content.installedHosts target="controller"}}>
+                  title='installed' {{action showHosts view.content.repositoryVersion.displayName view.content.installedHosts target="controller"}}>
                   <span>{{view.content.installedHosts.length}}</span>
                 </a>
               </span>
@@ -66,7 +66,7 @@
             <td class="current-hosts-count">
               <span {{bindAttr class="view.content.noCurrentHosts:not-active-link"}}>
                 <a href="#"
-                  title='current' {{action showHosts view.content.version view.content.currentHosts target="controller"}}>
+                  title='current' {{action showHosts view.content.repositoryVersion.displayName view.content.currentHosts target="controller"}}>
                   <span>{{view.content.currentHosts.length}}</span>
                 </a>
               </span>

+ 26 - 22
ambari-web/app/views/main/admin/stack_versions/stack_version_details_view.js

@@ -22,44 +22,37 @@ App.MainStackVersionsDetailsView = Em.View.extend({
 
   templateName: require('templates/main/admin/stack_versions/stack_version_details'),
 
-  /**
-   * installation status of stack version on hosts
-   * {String}
-   */
-  status: function() {
-    if (this.get('controller.installInProgress'))  {
-      return 'INSTALLING'
-    } else if (this.get('controller.allInstalled')) {
-      return 'ALL_INSTALLED';
-    } else {
-      return 'INSTALL';
-    }
-  }.property('controller.installInProgress', 'controller.allInstalled'),
-
+  content: function() {
+    return this.get('controller.content')
+  }.property('controller.content'),
   /**
    * text on install buttons
    * {String}
    */
   stackTextStatus: function() {
-    switch(this.get('status')) {
+    var self = this;
+    switch(this.get('content.state')) {
+      case 'UPGRADING':
       case 'INSTALLING':
-        return Em.I18n.t('admin.stackVersions.datails.hosts.btn.installing');
+        return self.get('content.state').toCapital().concat("...");
         break;
-      case 'ALL_INSTALLED':
+      case 'INSTALLED':
         return Em.I18n.t('admin.stackVersions.datails.hosts.btn.nothing');
         break;
-      case 'INSTALL':
-        return Em.I18n.t('admin.stackVersions.datails.hosts.btn.install').format(this.get('controller.content.notInstalledHostStacks.length'));
+      case 'INIT':
+        return Em.I18n.t('admin.stackVersions.datails.hosts.btn.install').format(self.get('totalHostCount') - self.get('content.installedHosts.length'));
         break;
+      default:
+        return self.get('content.state') && self.get('content.state').toCapital();
     }
-  }.property('status', 'controller.content.notInstalledHostStacks.length'),
+  }.property('content.state', 'content.notInstalledHostStacks.length'),
 
   /**
    * class on install buttons
    * {String}
    */
   statusClass: function() {
-    switch (this.get('status')) {
+    switch (this.get('content.state')) {
       case 'INSTALL':
         return 'btn-success';
         break;
@@ -69,6 +62,17 @@ App.MainStackVersionsDetailsView = Em.View.extend({
       default:
         return 'disabled';
     }
-  }.property('status')
+  }.property('content.state'),
+
+  didInsertElement: function() {
+    App.get('router.mainStackVersionsController').set('isPolling', true);
+    App.get('router.mainStackVersionsController').load();
+    App.get('router.mainStackVersionsController').doPolling();
+  },
+
 
+  willDestroyElement: function () {
+    App.get('router.mainStackVersionsController').set('isPolling', false);
+    clearTimeout(App.get('router.mainStackVersionsController.timeoutRef'));
+  }
 });

+ 30 - 16
ambari-web/app/views/main/admin/stack_versions/stack_version_view.js

@@ -42,10 +42,10 @@ App.MainStackVersionsView = App.TableView.extend({
   colPropAssoc: function () {
     var associations = [];
     associations[1] = 'name';
-    associations[2] = 'version';
-    associations[3] = 'operatingSystems';
-    associations[4] = 'installedHostsCount';
-    associations[5] = 'currentHostsCount';
+    associations[2] = 'repositoryVersion.displayName';
+    associations[3] = 'repositoryVersion.operatingSystems';
+    associations[4] = 'installedHosts.length';
+    associations[5] = 'currentHosts.length';
     return associations;
   }.property(),
 
@@ -59,24 +59,24 @@ App.MainStackVersionsView = App.TableView.extend({
   }),
   stackVersionSort: sort.fieldView.extend({
     column: 2,
-    name: 'version',
+    name: 'repositoryVersion.displayName',
     displayName: Em.I18n.t('admin.stackVersions.table.header.version'),
     type: 'version'
   }),
   osSort: sort.fieldView.extend({
     column: 3,
-    name: 'installedHostsCount',
+    name: 'repositoryVersionoperatingSystems',
     displayName: Em.I18n.t('admin.stackVersions.table.header.os')
   }),
-  istalledSort: sort.fieldView.extend({
+  installedSort: sort.fieldView.extend({
     column: 4,
-    name: 'currentHostsCount',
+    name: 'installedHosts.length',
     displayName: Em.I18n.t('admin.stackVersions.table.header.installed'),
     type: "number"
   }),
   currentSort: sort.fieldView.extend({
     column: 5,
-    name: 'currentHostsCount',
+    name: 'currentHosts.length',
     displayName: Em.I18n.t('admin.stackVersions.table.header.current'),
     type: "number"
   }),
@@ -85,15 +85,16 @@ App.MainStackVersionsView = App.TableView.extend({
     column: 1,
     fieldType: 'filter-input-width',
     content: function () {
+      var names = this.get('parentView.content').mapProperty('name').uniq();
       return [
         {
           value: '',
           label: Em.I18n.t('common.all')
         }
-      ].concat(App.StackVersion.find().map(function (service) {
+      ].concat(names.map(function (name) {
         return {
-          value: service.get('name'),
-          label: service.get('name')
+          value: name,
+          label: name
         }
       }));
     }.property('App.router.mainStackVersionsController.dataIsLoaded'),
@@ -118,7 +119,7 @@ App.MainStackVersionsView = App.TableView.extend({
     }
   }),
 
-  currentFilterView: filters.createTextView({
+  installedFilterView: filters.createTextView({
     column: 4,
     fieldType: 'filter-input-width',
     onChangeValue: function () {
@@ -126,7 +127,7 @@ App.MainStackVersionsView = App.TableView.extend({
     }
   }),
 
-  installedFilterView: filters.createTextView({
+  currentFilterView: filters.createTextView({
     column: 5,
     fieldType: 'filter-input-width',
     onChangeValue: function () {
@@ -134,6 +135,18 @@ App.MainStackVersionsView = App.TableView.extend({
     }
   }),
 
+  didInsertElement: function() {
+    this.set('controller.isPolling', true);
+    this.get('controller').load();
+    this.get('controller').doPolling();
+  },
+
+
+  willDestroyElement: function () {
+    this.set('controller.isPolling', false);
+    clearTimeout(this.get('controller.timeoutRef'));
+  },
+
   StackVersionView: Em.View.extend({
     tagName: 'tr',
     didInsertElement: function () {
@@ -147,8 +160,9 @@ App.MainStackVersionsView = App.TableView.extend({
     },
 
     labels: function() {
-      return this.get('content.operatingSystems').getEach('name').join("<br />");
-    }.property('content.operatingSystems.length')
+      return this.get('content.repositoryVersion.operatingSystems') &&
+        this.get('content.repositoryVersion.operatingSystems').getEach('osType').join("<br/>");
+    }.property('content.repositoryVersion.operatingSystems.length')
   })
 
 });

+ 4 - 7
ambari-web/test/controllers/main/admin/stack_version/stack_version_details_controller_test.js

@@ -68,28 +68,25 @@ describe('App.MainStackVersionsDetailsController', function () {
       App.set('testMode', false);
     });
     it("runs initPopup", function() {
-      mainStackVersionsDetailsController.reopen({'content': { 'version': "v1"}});
+      mainStackVersionsDetailsController.reopen({'content': { 'repositoryVersion': {'displayName': "v1"}}});
       var popupTitle = Em.I18n.t('admin.stackVersions.datails.install.hosts.popup.title').format("v1");
       var requestIds =[1];
       mainStackVersionsDetailsController.showProgressPopup();
       expect(App.router.get('highAvailabilityProgressPopupController').initPopup.calledWith(popupTitle, requestIds, mainStackVersionsDetailsController, true)).to.be.true;
     });
   });
-
+/** TODO after implementing correct api
   describe('#doInstallStackVersion', function () {
     beforeEach(function() {
       sinon.stub(App.ajax, 'send', Em.K);
-      sinon.stub(mainStackVersionsDetailsController, 'generateDataForInstall', Em.K);
     });
     afterEach(function() {
       App.ajax.send.restore();
-      mainStackVersionsDetailsController.generateDataForInstall.restore();
     });
     it("runs initPopup", function() {
-      mainStackVersionsDetailsController.doInstallStackVersion({});
-      expect(mainStackVersionsDetailsController.generateDataForInstall.calledOnce).to.be.true;
+      mainStackVersionsDetailsController.doInstallStackVersion(Em.Object.create({version: "1"}));
       expect(App.ajax.send.calledOnce).to.be.true;
     });
   });
-
+*/
 });

+ 4 - 4
ambari-web/test/views/main/admin/stack_version/stack_version_details_test.js

@@ -30,20 +30,20 @@ describe('App.MainStackVersionsDetailsView', function () {
   describe('#statusClass', function () {
     var tests = [
       {
-        status: "ALL_INSTALLED",
+        state: "ANY",
         buttonClass: 'disabled'
       },
       {
-        status: "INSTALL",
+        state: "INSTALL",
         buttonClass: 'btn-success'
       },
       {
-        status: "INSTALLING",
+        state: "INSTALLING",
         buttonClass: 'btn-primary'
       }
     ].forEach(function(t) {
       it("status is " + t.status + " class is " + t.buttonClass, function() {
-        mainStackVersionsDetailsView.reopen({'status': t.status});
+        mainStackVersionsDetailsView.reopen({ content: {'state': t.state}});
         expect(mainStackVersionsDetailsView.get('statusClass')).to.equal(t.buttonClass);
       });
     });