Kaynağa Gözat

AMBARI-778. Ensure data flows across all steps in installer wizard. (Jaimin Jetly via yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1393840 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 yıl önce
ebeveyn
işleme
f748b4ee90
30 değiştirilmiş dosya ile 962 ekleme ve 651 silme
  1. 119 30
      ambari-web/app/controllers/installer.js
  2. 19 3
      ambari-web/app/controllers/installer/step2_controller.js
  3. 16 7
      ambari-web/app/controllers/installer/step3_controller.js
  4. 18 79
      ambari-web/app/controllers/installer/step4_controller.js
  5. 60 28
      ambari-web/app/controllers/installer/step5_controller.js
  6. 8 14
      ambari-web/app/controllers/installer/step6_controller.js
  7. 55 36
      ambari-web/app/controllers/installer/step7_controller.js
  8. 19 11
      ambari-web/app/controllers/installer/step9_controller.js
  9. 0 245
      ambari-web/app/data/mock/service_components.js
  10. 84 0
      ambari-web/app/data/mock/services.js
  11. 245 0
      ambari-web/app/data/service_components.js
  12. 1 1
      ambari-web/app/messages.js
  13. 36 35
      ambari-web/app/models/form.js
  14. 2 2
      ambari-web/app/models/hosts.js
  15. 28 14
      ambari-web/app/models/service_config.js
  16. 18 2
      ambari-web/app/router.js
  17. 10 8
      ambari-web/app/routes/installer.js
  18. 10 10
      ambari-web/app/templates/installer.hbs
  19. 4 3
      ambari-web/app/templates/installer/step2.hbs
  20. 1 1
      ambari-web/app/templates/installer/step4.hbs
  21. 41 1
      ambari-web/app/views/installer.js
  22. 2 0
      ambari-web/app/views/installer/step2_view.js
  23. 1 3
      ambari-web/app/views/installer/step3_view.js
  24. 6 1
      ambari-web/app/views/installer/step4_view.js
  25. 6 1
      ambari-web/app/views/installer/step7_view.js
  26. 10 11
      ambari-web/app/views/installer/step9_view.js
  27. 5 0
      ambari-web/test/installer/step4_test.js
  28. 44 13
      ambari-web/test/installer/step5_test.js
  29. 94 81
      ambari-web/test/installer/step6_test.js
  30. 0 11
      ambari-web/test/installer/step7_test.js

+ 119 - 30
ambari-web/app/controllers/installer.js

@@ -23,26 +23,34 @@ App.InstallerController = Em.Controller.extend({
 
   name: 'installerController',
 
-  evaluateStep4: function () {
-    // TODO: evaluation at the end of step4
+  isStepDisabled: [],
 
-  },
-  evaluateStep5: function () {
-    // TODO: evaluation at the end of step5
-
-  },
-  evaluateStep6: function () {
-    // TODO: evaluation at the end of step6
-
-  },
-  evaluateStep7: function () {
-    // TODO: evaluation at the end of step7
+  totalSteps: 10,
 
+  init: function () {
+    this.clusters = App.Cluster.find();
+    this.isStepDisabled.pushObject(Ember.Object.create({
+      step: 1,
+      value: false
+    }));
+    for (var i = 2; i <= this.totalSteps; i++) {
+      this.isStepDisabled.pushObject(Ember.Object.create({
+        step: i,
+        value: true
+      }));
+    }
   },
-  evaluateStep8: function () {
-    // TODO: evaluation at the end of step8
 
-  },
+  setStepsEnable: function () {
+    for (var i = 2; i <= this.totalSteps; i++) {
+      var step = this.get('isStepDisabled').findProperty('step', i);
+      if (i <= this.get('currentStep')) {
+        step.set('value', false);
+      } else {
+        step.set('value', true);
+      }
+    }
+  }.observes('currentStep'),
 
   prevInstallStatus: function () {
     console.log('Inside the prevInstallStep function: The name is ' + App.router.get('loginController.loginName'));
@@ -58,50 +66,131 @@ App.InstallerController = Em.Controller.extend({
 
   clusters: null,
 
-  init: function () {
-    this.clusters = App.Cluster.find();
-  },
-
   isStep1: function () {
-    return this.get('currentStep') == '1';
+    return this.get('currentStep') == 1;
   }.property('currentStep'),
 
   isStep2: function () {
-    return this.get('currentStep') == '2';
+    return this.get('currentStep') == 2;
   }.property('currentStep'),
 
   isStep3: function () {
-    return this.get('currentStep') == '3';
+    return this.get('currentStep') == 3;
   }.property('currentStep'),
 
   isStep4: function () {
-    return this.get('currentStep') == '4';
+    return this.get('currentStep') == 4;
   }.property('currentStep'),
 
   isStep5: function () {
-    return this.get('currentStep') == '5';
+    return this.get('currentStep') == 5;
   }.property('currentStep'),
 
   isStep6: function () {
-    return this.get('currentStep') == '6';
+    return this.get('currentStep') == 6;
   }.property('currentStep'),
 
   isStep7: function () {
-    return this.get('currentStep') == '7';
+    return this.get('currentStep') == 7;
   }.property('currentStep'),
 
   isStep8: function () {
-    return this.get('currentStep') == '8';
+    return this.get('currentStep') == 8;
   }.property('currentStep'),
 
   isStep9: function () {
-    return this.get('currentStep') == '9';
+    return this.get('currentStep') == 9;
   }.property('currentStep'),
 
   isStep10: function () {
-    return this.get('currentStep') == '10';
+    return this.get('currentStep') == 10;
   }.property('currentStep'),
 
+  gotoStep1: function () {
+    if (this.get('isStepDisabled').findProperty('step', 1).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep1');
+    }
+
+  },
+
+  gotoStep2: function () {
+    if (this.get('isStepDisabled').findProperty('step', 2).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep2');
+    }
+
+  },
+
+  gotoStep3: function () {
+    if (this.get('isStepDisabled').findProperty('step', 3).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep3');
+    }
+
+  },
+
+  gotoStep4: function () {
+
+    if (this.get('isStepDisabled').findProperty('step', 4).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep4');
+    }
+  },
+
+  gotoStep5: function () {
+    if (this.get('isStepDisabled').findProperty('step', 5).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep5');
+    }
+  },
+
+  gotoStep6: function () {
+    if (this.get('isStepDisabled').findProperty('step', 6).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep6');
+    }
+
+  },
+
+  gotoStep7: function () {
+    if (this.get('isStepDisabled').findProperty('step', 7).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep7');
+    }
+  },
+
+  gotoStep8: function () {
+    if (this.get('isStepDisabled').findProperty('step', 8).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep8');
+    }
+  },
+
+  gotoStep9: function () {
+    if (this.get('isStepDisabled').findProperty('step', 9).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep9');
+    }
+  },
+
+  gotoStep10: function () {
+    if (this.get('isStepDisabled').findProperty('step', 10).get('value') === true) {
+      return;
+    } else {
+      App.router.send('gotoStep10');
+    }
+  },
+
   /**
    *
    * @param cluster ClusterModel

+ 19 - 3
ambari-web/app/controllers/installer/step2_controller.js

@@ -38,6 +38,22 @@ App.InstallerStep2Controller = Em.Controller.extend({
   softRepoLocalPathNullErr: false,
   isSubmitDisabled: false,
 
+
+  clearStep: function() {
+    this.set('hostNames','');
+    this.set('sshKey','');
+    this.set('passphrase','');
+    this.set('confirmPassphrase','');
+    this.set('localRepoPath','');
+  },
+
+  loadStep: function() {
+    if (App.router.get('isFwdNavigation') === true) {
+      console.log("MASTER TRACE: Loading step2: Install Options");
+      this.clearStep();
+    }
+  },
+
   installType: function () {
     if (this.get('manualInstall') === true) {
       return 'manualDriven';
@@ -53,7 +69,7 @@ App.InstallerStep2Controller = Em.Controller.extend({
   }.observes('localRepo'),
 
   validateHostNames: function () {
-    this.hostNameArr = this.get('hostNames').trim().split(new RegExp("\\s+","g"));
+    this.hostNameArr = this.get('hostNames').trim().split(new RegExp("\\s+", "g"));
     for (var index in this.hostNameArr) {
       console.log("host name is: " + this.hostNameArr[index]);
       //TODO: other validation for hostnames will be covered over here
@@ -170,7 +186,7 @@ App.InstallerStep2Controller = Em.Controller.extend({
 
     var validateResult = !this.validateStep2();
 
-    if (this.get('isSubmitDisabled') === true ) {
+    if (this.get('isSubmitDisabled') === true) {
       console.log("ERROR: error in validation");
       return false;
     } else {
@@ -207,7 +223,7 @@ App.InstallerStep2Controller = Em.Controller.extend({
         timeout: 2000,
         success: function () {
           console.log("TRACE: In success function for the post bootstrap function");
-          App.transitionTo('step3');
+          App.router.transitionTo('step3');
         },
         error: function () {
           console.log("ERROR: bootstrap post call failed");

+ 16 - 7
ambari-web/app/controllers/installer/step3_controller.js

@@ -15,6 +15,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 var App = require('app');
 
 App.InstallerStep3Controller = Em.ArrayController.extend({
@@ -38,13 +39,20 @@ App.InstallerStep3Controller = Em.ArrayController.extend({
   mockData: require('data/mock/step3_hosts'),
   mockRetryData: require('data/mock/step3_retry_hosts'),
 
+  loadStep: function () {
+    if (App.router.get('isFwdNavigation') === true) {
+      this.clear();
+      this.renderHosts(this.loadHosts());
+      this.startBootstrap();
+    }
+  },
+
   /* Loads the hostinfo from localStorage on the insertion of view. It's being called from view */
   loadHosts: function () {
-    this.clear();
     var hostInfo = [];
     hostInfo = App.db.getHosts();
     var hosts = new Ember.Set();
-    for( var index in hostInfo) {
+    for (var index in hostInfo) {
       hostInfo[index].status = "pending";
       hosts.add(hostInfo[index]);
       console.log("TRACE: host name is: " + hostInfo[index].name);
@@ -129,7 +137,7 @@ App.InstallerStep3Controller = Em.ArrayController.extend({
     this.removeObjects(hosts);
   },
 
-  removeBtn: function() {
+  removeBtn: function () {
     if (this.get('isSubmitDisabled')) {
       return;
     }
@@ -187,10 +195,10 @@ App.InstallerStep3Controller = Em.ArrayController.extend({
     // this.set('isSubmitDisabled',false);
   },
 
-  saveHostInfoToDb: function() {
+  saveHostInfoToDb: function () {
     var hostInfo = {};
     var succededHosts = this.filterProperty('status', 'success');
-    succededHosts.forEach(function(_host){
+    succededHosts.forEach(function (_host) {
       hostInfo[_host.name] = {
         name: _host.name,
         cpu: _host.cpu,
@@ -221,6 +229,7 @@ App.InstallerStep3Controller = Em.ArrayController.extend({
   // TODO: dummy button. Remove this after the hook up with actual REST API.
   mockBtn: function () {
     this.set('isSubmitDisabled', false);
+    this.clear();
     var hostInfo = this.mockData;
     this.renderHosts(hostInfo);
   },
@@ -239,10 +248,10 @@ App.InstallerStep3Controller = Em.ArrayController.extend({
     mockHosts.forEach(function (_host) {
       console.log('Retrying:  ' + _host.name);
     });
-    if(this.parseHostInfo(mockHosts, selectedHosts)) {
+    if (this.parseHostInfo(mockHosts, selectedHosts)) {
       this.saveHostInfoToDb();
     }
   }
 
-  });
+});
 

+ 18 - 79
ambari-web/app/controllers/installer/step4_controller.js

@@ -21,84 +21,18 @@ var db = require('utils/db');
 
 App.InstallerStep4Controller = Em.ArrayController.extend({
   name: 'installerStep4Controller',
-  rawContent: [
-    {
-      serviceName: 'HDFS',
-      displayName: 'HDFS',
-      isDisabled: true,
-      description: Em.I18n.t('services.hdfs.description')
-    },
-    {
-      serviceName: 'MAPREDUCE',
-      displayName: 'MapReduce',
-      isDisabled: false,
-      description: Em.I18n.t('services.mapreduce.description')
-    },
-    {
-      serviceName: 'NAGIOS',
-      displayName: 'Nagios',
-      isDisabled: false,
-      description: Em.I18n.t('services.nagios.description')
-    },
-    {
-      serviceName: 'GANGLIA',
-      displayName: 'Ganglia',
-      isDisabled: false,
-      description: Em.I18n.t('services.ganglia.description')
-    },
-    {
-      serviceName: 'HIVE',
-      displayName: 'Hive + HCatalog',
-      isDisabled: false,
-      description: Em.I18n.t('services.hive.description')
-    },
-    {
-      serviceName: 'HBASE',
-      displayName: 'HBase + ZooKeeper',
-      isDisabled: false,
-      description: Em.I18n.t('services.hbase.description')
-    },
-    {
-      serviceName: 'PIG',
-      displayName: 'Pig',
-      isDisabled: false,
-      description: Em.I18n.t('services.pig.description')
-    },
-    {
-      serviceName: 'SQOOP',
-      displayName: 'Sqoop',
-      isDisabled: false,
-      description: Em.I18n.t('services.sqoop.description')
-    },
-    {
-      serviceName: 'OOZIE',
-      displayName: 'Oozie',
-      isDisabled: false,
-      description: Em.I18n.t('services.oozie.description')
-    },
-    {
-      serviceName: 'ZOOKEEPER',
-      isDisabled: false,
-      isHidden: true
-    },
-    {
-      serviceName: 'HCATALOG',
-      isDisabled: false,
-      isHidden: true
-    }
-  ],
-
+  rawContent: require('data/mock/services'),
   content: [],
 
-  isAll: function() {
+  isAll: function () {
     return this.everyProperty('isSelected', true);
   }.property('@each.isSelected'),
 
-  isMinimum: function() {
+  isMinimum: function () {
     return this.filterProperty('isDisabled', false).everyProperty('isSelected', false);
   }.property('@each.isSelected'),
 
-  checkDependencies: function() {
+  checkDependencies: function () {
     var hbase = this.findProperty('serviceName', 'HBASE');
     var zookeeper = this.findProperty('serviceName', 'ZOOKEEPER');
     if (hbase && zookeeper) {
@@ -111,26 +45,32 @@ App.InstallerStep4Controller = Em.ArrayController.extend({
     }
   }.observes('@each.isSelected'),
 
-  init: function() {
-    this._super();
-    // wrap each item with Ember.Object
-    this.rawContent.forEach(function(item) {
+  loadStep: function () {
+    if (App.router.get('isFwdNavigation') === true) {
+      console.log("MASTER TRACE: Loading step4: Choose Services");
+      this.clear();
+      this.renderStep(this.rawContent);
+    }
+  },
+
+  renderStep: function (rawContent) {
+    rawContent.forEach(function (item) {
       item.isSelected = true;
       this.pushObject(Ember.Object.create(item));
     }, this);
   },
 
-  selectAll: function() {
+  selectAll: function () {
     this.setEach('isSelected', true);
   },
 
-  selectMinimum: function() {
+  selectMinimum: function () {
     this.filterProperty('isDisabled', false).setEach('isSelected', false);
   },
 
-  saveSelectedServiceNamesToDB: function() {
+  saveSelectedServiceNamesToDB: function () {
     var serviceNames = [];
-    this.filterProperty('isSelected', true).forEach(function(item){
+    this.filterProperty('isSelected', true).forEach(function (item) {
       serviceNames.push(item.serviceName);
     });
     db.setSelectedServiceNames(serviceNames);
@@ -194,5 +134,4 @@ App.InstallerStep4Controller = Em.ArrayController.extend({
     this.saveSelectedServiceNamesToDB();
     App.router.send('next');
   }
-
 })

+ 60 - 28
ambari-web/app/controllers/installer/step5_controller.js

@@ -24,7 +24,8 @@ App.InstallerStep5Controller = Em.Controller.extend({
   hosts: [],
   selectedServices: [],
   selectedServicesMasters: [],
-  components: require('data/mock/service_components'),
+  zId: 0,
+  components: require('data/service_components'),
 
   /*
    Below function retrieves host information from local storage
@@ -34,14 +35,16 @@ App.InstallerStep5Controller = Em.Controller.extend({
     this.set('hosts', []);
     this.set('selectedServices', []);
     this.set('selectedServicesMasters', []);
-    //this.selectedServices = [];
-    //this.selectedServicesMasters = [];
+    this.set('zId', 0);
   },
 
   loadStep: function () {
-    this.clearStep();
-    this.renderHostInfo(this.loadHostInfo());
-    this.renderComponents(this.loadComponents(this.loadServices()));
+    if (App.router.get('isFwdNavigation') === true) {
+      console.log("TRACE: Loading step5: Assign Masters");
+      this.clearStep();
+      this.renderHostInfo(this.loadHostInfo());
+      this.renderComponents(this.loadComponents(this.loadServices()));
+    }
   },
 
   loadHostInfo: function () {
@@ -56,10 +59,8 @@ App.InstallerStep5Controller = Em.Controller.extend({
     return hosts;
   },
 
-  renderHostInfo: function (hostsInfo) {
 
-    var zookeeperComponent = null, componentObj = null, hostObj = null;
-    // this._super();
+  renderHostInfo: function (hostsInfo) {
 
     //wrap the model data into
 
@@ -73,9 +74,10 @@ App.InstallerStep5Controller = Em.Controller.extend({
       hostObj.set("host_info", "" + hostObj.get("host_name") + " ( " + hostObj.get("memory") + "GB" + " " + hostObj.get("cpu") + "cores )");
       this.get("hosts").pushObject(hostObj);
     }, this);
-  },
 
 
+  },
+
   loadServices: function () {
     var services = App.db.getSelectedServiceNames();
     services.forEach(function (item) {
@@ -107,31 +109,47 @@ App.InstallerStep5Controller = Em.Controller.extend({
     return components;
   },
 
+  getMasterComponents: function () {
+    return (this.get('selectedServicesMasters').slice(0));
+  },
+
   renderComponents: function (masterComponents) {
-    var self = this;
     var zookeeperComponent = null, componentObj = null;
+    var services = [];
+    services = this.getMasterComponents();
+    if (services.length) {
+      this.set('selectedServicesMasters', []);
+    }
+
 
     masterComponents.forEach(function (item) {
       //add the zookeeper component at the end if exists
       if (item.component_name === "ZooKeeper") {
+        if (services.length) {
+          services.forEach(function (_service) {
+            this.get('selectedServicesMasters').pushObject(_service);
+          }, this);
+        }
+        this.set('zId', this.get('zId') + 1);
         zookeeperComponent = Ember.Object.create(item);
+        zookeeperComponent.set('zId', this.get('zId'));
+        zookeeperComponent.set("showAddControl", true);
+        if (zookeeperComponent.get('zId') === 1) {
+          zookeeperComponent.set("showRemoveControl", false);
+        } else {
+          zookeeperComponent.set("showRemoveControl", true);
+        }
+
+        zookeeperComponent.set("availableHosts", this.get("hosts").slice(0));
+        this.get("selectedServicesMasters").pushObject(Ember.Object.create(zookeeperComponent));
+
       } else {
         componentObj = Ember.Object.create(item);
         componentObj.set("availableHosts", this.get("hosts").slice(0));
-        self.get("selectedServicesMasters").pushObject(componentObj);
+        this.get("selectedServicesMasters").pushObject(componentObj);
       }
     }, this);
 
-    //while initialization of the controller there will be only 1 zookeeper server
-
-    if (zookeeperComponent) {
-      zookeeperComponent.set("showAddControl", true);
-      zookeeperComponent.set("showRemoveControl", false);
-      zookeeperComponent.set("zId", 1);
-      zookeeperComponent.set("availableHosts", this.get("hosts").slice(0));
-      this.get("selectedServicesMasters").pushObject(Ember.Object.create(zookeeperComponent));
-    }
-
   },
 
   getKerberosServer: function (noOfHosts) {
@@ -255,7 +273,11 @@ App.InstallerStep5Controller = Em.Controller.extend({
 
   getZooKeeperServer: function (noOfHosts) {
     var hosts = this.get('hosts');
-    return hosts[0];
+    if (noOfHosts < 3) {
+      return [hosts[0].host_name];
+    } else {
+      return [hosts[0].host_name, hosts[1].host_name, hosts[2].host_name];
+    }
   },
 
   getGangliaServer: function (noOfHosts) {
@@ -290,6 +312,7 @@ App.InstallerStep5Controller = Em.Controller.extend({
     }
   },
 
+
   selectHost: function (componentName) {
     var noOfHosts = this.get('hosts').length;
     if (componentName === 'KERBEROS_SERVER') {
@@ -309,7 +332,19 @@ App.InstallerStep5Controller = Em.Controller.extend({
     } else if (componentName === 'TEMPLETON_SERVER') {
       return this.getTempletonServer(noOfHosts).host_name;
     } else if (componentName === 'ZOOKEEPER_SERVER') {
-      return this.getZooKeeperServer(noOfHosts).host_name;
+      var zhosts = this.getZooKeeperServer(noOfHosts);
+      var extraHosts = zhosts.slice(0, zhosts.length - 1);
+      var zooKeeperHosts = new Ember.Set();
+      extraHosts.forEach(function (_host) {
+        var zooKeeperHost = {};
+        zooKeeperHost.component_name = 'ZooKeeper';
+        zooKeeperHost.selectedHost = _host;
+        zooKeeperHost.availableHosts = [];
+        zooKeeperHosts.add(zooKeeperHost);
+      });
+      this.renderComponents(zooKeeperHosts);
+      var lastHost = zhosts[zhosts.length - 1];
+      return lastHost;
     } else if (componentName === 'GANGLIA_MONITOR_SERVER') {
       return this.getGangliaServer(noOfHosts);
     } else if (componentName === 'NAGIOS_SERVER') {
@@ -326,6 +361,7 @@ App.InstallerStep5Controller = Em.Controller.extend({
 
     mappedHosts.forEach(function (item) {
       hostObj = self.get("hosts").findProperty("host_name", item);
+      console.log("Name of the host is: " + hostObj.host_name);
       hostInfo = " ( " + hostObj.get("memory") + "GB" + " " + hostObj.get("cpu") + "cores )";
 
       mappingObject = Ember.Object.create({
@@ -358,13 +394,11 @@ App.InstallerStep5Controller = Em.Controller.extend({
 
     if (componentName === "ZooKeeper") {
       zookeeperHosts = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").mapProperty("selectedHost").uniq();
-
       this.get("hosts").forEach(function (item) {
         if (!(zookeeperHosts.contains(item.get("host_name")))) {
           assignableHosts.pushObject(item);
         }
       }, this);
-
       return assignableHosts;
 
     } else {
@@ -374,7 +408,6 @@ App.InstallerStep5Controller = Em.Controller.extend({
 
   assignHostToMaster: function (masterService, selectedHost, zId) {
     if (selectedHost && masterService) {
-
       if ((masterService === "ZooKeeper") && zId) {
         this.get('selectedServicesMasters').findProperty("zId", zId).set("selectedHost", selectedHost);
         this.rebalanceZookeeperHosts();
@@ -467,7 +500,6 @@ App.InstallerStep5Controller = Em.Controller.extend({
       if (currentZooKeepers.get("length") < this.get("hosts.length")) {
         currentZooKeepers.set("lastObject.showAddControl", true);
       }
-
       this.rebalanceZookeeperHosts();
 
       return true;

+ 8 - 14
ambari-web/app/controllers/installer/step6_controller.js

@@ -104,9 +104,12 @@ App.InstallerStep6Controller = Em.Controller.extend({
   },
 
   loadStep: function () {
-    this.set('hosts',[]);
-    this.set('showHbase',this.isHbaseSelected());
-    this.setSlaveHost(this.getHostNames());
+    if (App.router.get('isFwdNavigation') === true) {
+      console.log("TRACE: Loading step6: Assign Slaves");
+      this.set('hosts', []);
+      this.set('showHbase', this.isHbaseSelected());
+      this.setSlaveHost(this.getHostNames());
+    }
   },
 
   setSlaveHost: function (hostNames) {
@@ -117,7 +120,7 @@ App.InstallerStep6Controller = Em.Controller.extend({
         isTaskTracker: !this.hasMasterComponents(_hostName),
         isRegionServer: !this.hasMasterComponents(_hostName)
       }));
-    },this);
+    }, this);
   },
 
   getHostNames: function () {
@@ -130,15 +133,6 @@ App.InstallerStep6Controller = Em.Controller.extend({
     return hostNames;
   },
 
-
-  /*  init: function () {
-   this._super();
-   this.get('rawHosts').forEach(function (host) {
-   host.isDataNode = host.isTaskTracker = host.isRegionServer = !this.hasMasterComponents(host.hostname);
-   this.get('hosts').pushObject(Ember.Object.create(host));
-   }, this);
-   },
-   */
   validate: function () {
     return !(this.get('isNoDataNodes') || this.get('isNoTaskTrackers') || this.get('isNoRegionServers'));
   },
@@ -173,7 +167,7 @@ App.InstallerStep6Controller = Em.Controller.extend({
           group: 'Default'
         });
       }
-    },this);
+    }, this);
 
     var slaveComponentHosts = [];
     slaveComponentHosts.push({

+ 55 - 36
ambari-web/app/controllers/installer/step7_controller.js

@@ -46,9 +46,21 @@ App.InstallerStep7Controller = Em.ArrayController.extend({
   // TODO: set attributes from localStorage in router
   selectedServiceNames: [ 'HDFS', 'MAPREDUCE', 'GANGLIA', 'NAGIOS', 'HBASE', 'PIG', 'SQOOP', 'OOZIE', 'HIVE', 'ZOOKEEPER'],
   masterComponentHosts: require('data/mock/master_component_hosts'),
-  slaveComponentHosts: require('data/mock/slave_component_hosts'),
+  slaveComponentHosts: [],
 
-  doInit: true,
+  clearStep: function () {
+    this.clear();
+    this.selectedServiceNames.clear();
+    this.masterComponentHosts.clear();
+    this.slaveComponentHosts.clear();
+  },
+
+  loadStep: function () {
+    if (App.router.get('isFwdNavigation') === true) {
+      this.clearStep();
+      this.renderConfigs(this.loadConfigs());
+    }
+  },
 
   loadConfigs: function () {
 
@@ -65,58 +77,59 @@ App.InstallerStep7Controller = Em.ArrayController.extend({
     if (slaveComponentHostsInDB != undefined) {
       this.set('slaveComponentHosts', slaveComponentHostsInDB);
     }
+    var serviceConfigs = require('data/service_configs');
+    return serviceConfigs;
 
-    // TODO: check App.db to see if configs have been saved already
-    if (this.doInit) {
-      var serviceConfigs = require('data/service_configs');
+  },
 
-      var self = this;
+  renderConfigs: function(serviceConfigs) {
+    var self = this;
 
-      this.set('content', []);
+    serviceConfigs.forEach(function (_serviceConfig) {
+      var serviceConfig = App.ServiceConfig.create({
+        serviceName: _serviceConfig.serviceName,
+        displayName: _serviceConfig.displayName,
+        configCategories: _serviceConfig.configCategories,
+        configs: []
+      });
 
-      serviceConfigs.forEach(function (_serviceConfig) {
-        var serviceConfig = App.ServiceConfig.create({
-          serviceName: _serviceConfig.serviceName,
-          displayName: _serviceConfig.displayName,
-          configCategories: _serviceConfig.configCategories,
-          configs: []
+      if (self.selectedServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
+        _serviceConfig.configs.forEach(function (_serviceConfigProperty) {
+          var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
+          serviceConfigProperty.serviceConfig = serviceConfig;
+          serviceConfigProperty.initialValue();
+          serviceConfig.configs.pushObject(serviceConfigProperty);
+          serviceConfigProperty.validate();
         });
 
-        if (self.selectedServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
-          _serviceConfig.configs.forEach(function (_serviceConfigProperty) {
-            var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
-            serviceConfigProperty.serviceConfig = serviceConfig;
-            serviceConfig.configs.pushObject(serviceConfigProperty);
-            serviceConfigProperty.validate();
-          });
-
-          console.log('pushing ' + serviceConfig.serviceName);
-          self.content.pushObject(serviceConfig);
-        } else {
-          console.log('skipping ' + serviceConfig.serviceName);
-        }
-      });
+        console.log('pushing ' + serviceConfig.serviceName);
+        self.content.pushObject(serviceConfig);
+      } else {
+        console.log('skipping ' + serviceConfig.serviceName);
+      }
+    });
+
+    this.set('selectedService', this.objectAt(0));
 
-      this.set('selectedService', this.objectAt(0));
-      this.doInit = false;
-    }
   },
 
+
+
   submit: function () {
     if (!this.get('isSubmitDisabled')) {
       // TODO:
       // save service configs in App.db (localStorage)
       var serviceConfigProperties = [];
-      this.content.forEach(function(_content){
+      this.content.forEach(function (_content) {
         var config = [];
         config = _content.configs;
-        config.forEach(function(_configProperties){
+        config.forEach(function (_configProperties) {
           serviceConfigProperties.push(_configProperties);
           console.log('TRACE: pushing: ' + _configProperties.name);
           console.log('INFO: value: ' + _configProperties.value);
-        },this);
+        }, this);
 
-      },this);
+      }, this);
       db.setServiceConfigProperties(serviceConfigProperties);
       App.router.send('next');
       //App.get('router').transitionTo('step8');
@@ -161,6 +174,8 @@ App.SlaveComponentGroupsController = Ember.ArrayController.extend({
         return 'TaskTracker';
       case 'HBASE':
         return 'RegionServer';
+      default:
+        return null;
     }
 
   }.property('App.router.installerStep7Controller.selectedService'),
@@ -183,11 +198,15 @@ App.SlaveComponentGroupsController = Ember.ArrayController.extend({
   },
 
   hosts: function () {
-    return this.findProperty('componentName', this.get('selectedComponentName')).hosts;
+    if (this.get('selectedComponentName') !== null) {
+      return this.findProperty('componentName', this.get('selectedComponentName')).hosts;
+    }
   }.property('@each.hosts', 'selectedComponentName'),
 
   groups: function () {
-    return this.findProperty('componentName', this.get('selectedComponentName')).hosts.mapProperty('group').uniq();
+    if (this.get('selectedComponentName') !== null) {
+      return this.findProperty('componentName', this.get('selectedComponentName')).hosts.mapProperty('group').uniq();
+    }
   }.property('@each.hosts', 'selectedComponentName')
 
 });

+ 19 - 11
ambari-web/app/controllers/installer/step9_controller.js

@@ -23,7 +23,7 @@ App.InstallerStep9Controller = Em.ArrayController.extend({
   progress: '0',
   // result: 'pending', // val = pending or success or failed
   isStepCompleted: false,
-  isSubmitDisabled: function() {
+  isSubmitDisabled: function () {
     return !this.get('isStepCompleted');
   }.property('isStepCompleted'),
 
@@ -33,6 +33,14 @@ App.InstallerStep9Controller = Em.ArrayController.extend({
   pollData_2: require('data/mock/step9_pollData_2'),
   pollDataCounter: 0,
 
+  loadStep: function () {
+    if (App.router.get('isFwdNavigation') === true) {
+      console.log("TRACE: Loading step9: Install, Start and Test");
+      this.clear();
+      this.renderHosts(this.loadHosts());
+    }
+  },
+
   loadHosts: function () {
     var hostInfo = [];
     hostInfo = App.db.getHosts();
@@ -112,7 +120,7 @@ App.InstallerStep9Controller = Em.ArrayController.extend({
   },
 
 
-  getFailedHostsForFailedRoles: function(polledData) {
+  getFailedHostsForFailedRoles: function (polledData) {
     var hostArr = new Ember.Set();
     polledData.forEach(function (_polledData) {
       var successFactor = _polledData.sf;
@@ -120,10 +128,10 @@ App.InstallerStep9Controller = Em.ArrayController.extend({
       var actionsFailed = actionsPerRole.filterProperty('status', 'failed');
       var actionsAborted = actionsPerRole.filterProperty('status', 'aborted');
       if ((((actionsFailed.length + actionsAborted.length) / actionsPerRole.length) * 100) <= successFactor) {
-        actionsFailed.forEach(function(_actionFailed) {
+        actionsFailed.forEach(function (_actionFailed) {
           hostArr.add(_actionFailed.name);
         });
-        actionsAborted.forEach(function(_actionFailed) {
+        actionsAborted.forEach(function (_actionFailed) {
           hostArr.add(_actionFailed.name);
         });
       }
@@ -131,11 +139,11 @@ App.InstallerStep9Controller = Em.ArrayController.extend({
     return hostArr;
   },
 
-  setHostsStatus: function(hosts,status) {
+  setHostsStatus: function (hosts, status) {
     var self = this;
-    hosts.forEach(function(_host){
-      var host = self.findProperty('name',_host);
-      host.set('status',status);
+    hosts.forEach(function (_host) {
+      var host = self.findProperty('name', _host);
+      host.set('status', status);
     });
   },
 
@@ -150,10 +158,10 @@ App.InstallerStep9Controller = Em.ArrayController.extend({
       } else {
         if (this.isStepFailed(polledData)) {
           self.set('status', 'failed');
-          this.setHostsStatus(this.getFailedHostsForFailedRoles(polledData),'failed');
+          this.setHostsStatus(this.getFailedHostsForFailedRoles(polledData), 'failed');
         }
       }
-      this.set('isStepCompleted',true);
+      this.set('isStepCompleted', true);
     }
   },
 
@@ -165,7 +173,7 @@ App.InstallerStep9Controller = Em.ArrayController.extend({
     var totalProgress = 0;
     this.forEach(function (_content) {
       var actions = polledData.filterProperty('name', _content.name);
-      if(actions.length === 0) {
+      if (actions.length === 0) {
         alert('For testing with mockData follow the sequence: hit referesh,"mockData btn", "pollData btn", again "pollData btn"');
         //exit();
       }

+ 0 - 245
ambari-web/app/data/mock/service_components.js

@@ -1,245 +0,0 @@
-/**
- * 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.
- */
-
-module.exports = new Ember.Set([
-
-      {
-        service_name: 'HDFS',
-        component_name: 'NAMENODE',
-        display_name: 'NameNode',
-        isMaster: true,
-        isClient: false,
-        description: 'Master server that manages the file system namespace and regulates access to files by clients'
-      },
-      {
-        service_name: 'HDFS',
-        component_name: 'SNAMENODE',
-        display_name: 'SNameNode',
-        isMaster: true,
-        isClient: false,
-        description: 'Helper to the primary NameNode that is responsible for supporting periodic checkpoints of the HDFS metadata'
-      },
-      {
-        service_name: 'HDFS',
-        component_name: 'DATANODE',
-        display_name: 'Datanode',
-        isMaster: false,
-        isClient: false,
-        description: 'The slave for HDFS'
-      },
-      {
-        service_name: 'HDFS',
-        component_name: 'HDFS_CLIENT',
-        display_name: 'HDFS Client',
-        isMaster: false,
-        isClient: true,
-        description: 'Client component for HDFS'
-      },
-      {
-        service_name: 'MAPREDUCE',
-        component_name: 'JOBTRACKER',
-        display_name: 'JobTracker',
-        isMaster: true,
-        isClient: false,
-        description: 'Central Master service that pushes work (MR tasks) out to available TaskTracker nodes in the cluster'
-      },
-      {
-        service_name: 'MAPREDUCE',
-        component_name: 'TASKTRACKER',
-        display_name: 'TaskTracker',
-        isMaster: false,
-        isClient: false,
-        description: 'The slave for MapReduce'
-      },
-      {
-        service_name: 'MAPREDUCE',
-        component_name: 'MAPREDUCE_CLIENT',
-        display_name: 'MapReduce Client',
-        isMaster: false,
-        isClient: true,
-        description: 'Client component for MapReduce'
-      },
-      {
-        service_name: 'ZOOKEEPER',
-        component_name: 'ZOOKEEPER_SERVER',
-        display_name: 'ZooKeeper',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'ZOOKEEPER',
-        component_name: 'ZOOKEEPER_CLIENT',
-        display_name: 'ZooKeeper Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      },
-      {
-        service_name: 'HBASE',
-        component_name: 'HBASE_MASTER',
-        display_name: 'HBase Master',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'HBASE',
-        component_name: 'HBASE_REGIONSERVER',
-        display_name: 'HBase Region Server',
-        isMaster: false,
-        isClient: false,
-        description: 'The slave for HBase'
-      },
-      {
-        service_name: 'HBASE',
-        component_name: 'HBASE_CLIENT',
-        display_name: 'HBase Client',
-        isMaster: false,
-        isClient: true,
-        description: 'The slave for HBase'
-      },
-      {
-        service_name: 'PIG',
-        component_name: 'PIG_CLIENT',
-        display_name: 'Pig Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      },
-      {
-        service_name: 'SQOOP',
-        component_name: 'SQOOP_CLIENT',
-        display_name: 'Sqoop Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      },
-      {
-        service_name: 'OOZIE',
-        component_name: 'OOZIE_SERVER',
-        display_name: 'Oozie Server',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'OOZIE',
-        component_name: 'OOZIE_CLIENT',
-        display_name: 'Oozie Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      },
-      {
-        service_name: 'HIVE',
-        component_name: 'HIVE_SERVER',
-        display_name: 'Hive Metastore',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'HIVE',
-        component_name: 'HIVE_CLIENT',
-        display_name: 'Hive Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      },
-      {
-        service_name: 'HIVE',
-        component_name: 'HIVE_MYSQL',
-        display_name: 'MySql Server for Hive',
-        isMaster: false,
-        isClient: false,
-        description: 'The slave for HBase'
-      },
-      {
-        service_name: 'TEMPLETON',
-        component_name: 'TEMPLETON_SERVER',
-        display_name: 'Templeton Server',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'TEMPLETON',
-        component_name: 'TEMPLETON_CLIENT',
-        display_name: 'Templeton Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      },
-      {
-        service_name: 'DASHBOARD',
-        component_name: 'DASHBOARD',
-        display_name: 'Monitoring Dashboard',
-        isMaster: false,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'NAGIOS',
-        component_name: 'NAGIOS_SERVER',
-        display_name: 'Nagios Server',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'GANGLIA',
-        component_name: 'GANGLIA_MONITOR_SERVER',
-        display_name: 'Ganglia Collector',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'GANGLIA',
-        component_name: 'GANGLIA_MONITOR',
-        display_name: 'Ganglia Slave',
-        isMaster: false,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'KERBEROS',
-        component_name: 'KERBEROS_SERVER',
-        display_name: 'Kerberos Server',
-        isMaster: true,
-        isClient: false,
-        description: ''
-      },
-      {
-        service_name: 'KERBEROS',
-        component_name: 'KERBEROS_ADMIN_CLIENT',
-        display_name: 'Kerberos Admin Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      },
-      {
-        service_name: 'KERBEROS',
-        component_name: 'KERBEROS_CLIENT',
-        display_name: 'Kerberos Client',
-        isMaster: false,
-        isClient: true,
-        description: ''
-      }
-]);

+ 84 - 0
ambari-web/app/data/mock/services.js

@@ -0,0 +1,84 @@
+/**
+ * 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.
+ */
+
+module.exports = [
+  {
+    serviceName: 'HDFS',
+    displayName: 'HDFS',
+    isDisabled: true,
+    description: Em.I18n.t('services.hdfs.description')
+  },
+  {
+    serviceName: 'MAPREDUCE',
+    displayName: 'MapReduce',
+    isDisabled: false,
+    description: Em.I18n.t('services.mapreduce.description')
+  },
+  {
+    serviceName: 'NAGIOS',
+    displayName: 'Nagios',
+    isDisabled: false,
+    description: Em.I18n.t('services.nagios.description')
+  },
+  {
+    serviceName: 'GANGLIA',
+    displayName: 'Ganglia',
+    isDisabled: false,
+    description: Em.I18n.t('services.ganglia.description')
+  },
+  {
+    serviceName: 'HIVE',
+    displayName: 'Hive + HCatalog',
+    isDisabled: false,
+    description: Em.I18n.t('services.hive.description')
+  },
+  {
+    serviceName: 'HBASE',
+    displayName: 'HBase + ZooKeeper',
+    isDisabled: false,
+    description: Em.I18n.t('services.hbase.description')
+  },
+  {
+    serviceName: 'PIG',
+    displayName: 'Pig',
+    isDisabled: false,
+    description: Em.I18n.t('services.pig.description')
+  },
+  {
+    serviceName: 'SQOOP',
+    displayName: 'Sqoop',
+    isDisabled: false,
+    description: Em.I18n.t('services.sqoop.description')
+  },
+  {
+    serviceName: 'OOZIE',
+    displayName: 'Oozie',
+    isDisabled: false,
+    description: Em.I18n.t('services.oozie.description')
+  },
+  {
+    serviceName: 'ZOOKEEPER',
+    isDisabled: false,
+    isHidden: true
+  },
+  {
+    serviceName: 'HCATALOG',
+    isDisabled: false,
+    isHidden: true
+  }
+]

+ 245 - 0
ambari-web/app/data/service_components.js

@@ -0,0 +1,245 @@
+/**
+ * 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.
+ */
+
+module.exports = new Ember.Set([
+
+  {
+    service_name: 'HDFS',
+    component_name: 'NAMENODE',
+    display_name: 'NameNode',
+    isMaster: true,
+    isClient: false,
+    description: 'Master server that manages the file system namespace and regulates access to files by clients'
+  },
+  {
+    service_name: 'HDFS',
+    component_name: 'SNAMENODE',
+    display_name: 'SNameNode',
+    isMaster: true,
+    isClient: false,
+    description: 'Helper to the primary NameNode that is responsible for supporting periodic checkpoints of the HDFS metadata'
+  },
+  {
+    service_name: 'HDFS',
+    component_name: 'DATANODE',
+    display_name: 'Datanode',
+    isMaster: false,
+    isClient: false,
+    description: 'The slave for HDFS'
+  },
+  {
+    service_name: 'HDFS',
+    component_name: 'HDFS_CLIENT',
+    display_name: 'HDFS Client',
+    isMaster: false,
+    isClient: true,
+    description: 'Client component for HDFS'
+  },
+  {
+    service_name: 'MAPREDUCE',
+    component_name: 'JOBTRACKER',
+    display_name: 'JobTracker',
+    isMaster: true,
+    isClient: false,
+    description: 'Central Master service that pushes work (MR tasks) out to available TaskTracker nodes in the cluster'
+  },
+  {
+    service_name: 'MAPREDUCE',
+    component_name: 'TASKTRACKER',
+    display_name: 'TaskTracker',
+    isMaster: false,
+    isClient: false,
+    description: 'The slave for MapReduce'
+  },
+  {
+    service_name: 'MAPREDUCE',
+    component_name: 'MAPREDUCE_CLIENT',
+    display_name: 'MapReduce Client',
+    isMaster: false,
+    isClient: true,
+    description: 'Client component for MapReduce'
+  },
+  {
+    service_name: 'ZOOKEEPER',
+    component_name: 'ZOOKEEPER_SERVER',
+    display_name: 'ZooKeeper',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'ZOOKEEPER',
+    component_name: 'ZOOKEEPER_CLIENT',
+    display_name: 'ZooKeeper Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'HBASE',
+    component_name: 'HBASE_MASTER',
+    display_name: 'HBase Master',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'HBASE',
+    component_name: 'HBASE_REGIONSERVER',
+    display_name: 'HBase Region Server',
+    isMaster: false,
+    isClient: false,
+    description: 'The slave for HBase'
+  },
+  {
+    service_name: 'HBASE',
+    component_name: 'HBASE_CLIENT',
+    display_name: 'HBase Client',
+    isMaster: false,
+    isClient: true,
+    description: 'The slave for HBase'
+  },
+  {
+    service_name: 'PIG',
+    component_name: 'PIG_CLIENT',
+    display_name: 'Pig Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'SQOOP',
+    component_name: 'SQOOP_CLIENT',
+    display_name: 'Sqoop Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'OOZIE',
+    component_name: 'OOZIE_SERVER',
+    display_name: 'Oozie Server',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'OOZIE',
+    component_name: 'OOZIE_CLIENT',
+    display_name: 'Oozie Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'HIVE',
+    component_name: 'HIVE_SERVER',
+    display_name: 'Hive Metastore',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'HIVE',
+    component_name: 'HIVE_CLIENT',
+    display_name: 'Hive Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'HIVE',
+    component_name: 'HIVE_MYSQL',
+    display_name: 'MySql Server for Hive',
+    isMaster: false,
+    isClient: false,
+    description: 'The slave for HBase'
+  },
+  {
+    service_name: 'TEMPLETON',
+    component_name: 'TEMPLETON_SERVER',
+    display_name: 'Templeton Server',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'TEMPLETON',
+    component_name: 'TEMPLETON_CLIENT',
+    display_name: 'Templeton Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'DASHBOARD',
+    component_name: 'DASHBOARD',
+    display_name: 'Monitoring Dashboard',
+    isMaster: false,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'NAGIOS',
+    component_name: 'NAGIOS_SERVER',
+    display_name: 'Nagios Server',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'GANGLIA',
+    component_name: 'GANGLIA_MONITOR_SERVER',
+    display_name: 'Ganglia Collector',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'GANGLIA',
+    component_name: 'GANGLIA_MONITOR',
+    display_name: 'Ganglia Slave',
+    isMaster: false,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'KERBEROS',
+    component_name: 'KERBEROS_SERVER',
+    display_name: 'Kerberos Server',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'KERBEROS',
+    component_name: 'KERBEROS_ADMIN_CLIENT',
+    display_name: 'Kerberos Admin Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'KERBEROS',
+    component_name: 'KERBEROS_CLIENT',
+    display_name: 'Kerberos Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  }
+]);

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

@@ -70,7 +70,7 @@ Em.I18n.translations = {
     'This file instructs package manager to use your local software repository to retrieve software packages, instead of ' +
     'downloading from the internet.</p>',
   'installer.step2.localRepo.tooltip.title': 'Local Software Repository',
-  'installer.step2.localRepo.tooltip.content': 'The repository configuration file should be installed on each host' +
+  'installer.step2.localRepo.tooltip.content': 'The repository configuration file should be installed on each host ' +
     'in your cluster. This file instructs package manager to use your local' +
     'software repository to retrieve software packages, instead of using the internet.',
   'installer.step2.manualInstall.tooltip.title': 'Not Using SSH (Manual Install)',

+ 36 - 35
ambari-web/app/models/form.js

@@ -23,17 +23,17 @@ App.Form = Em.View.extend({
   /**
    * generating fields from fieldsOptions
    */
-  classNames:["form-horizontal"],
-  i18nprefix:'form.',
-  fields:[],
-  field:{},
-  messages:[],
-  object:false,
-  result:0, // save result var (-1 - error; 0 - init; 1 - success)
-  templateName:require('templates/common/form'),
-  tagName:'form',
+  classNames: ["form-horizontal"],
+  i18nprefix: 'form.',
+  fields: [],
+  field: {},
+  messages: [],
+  object: false,
+  result: 0, // save result var (-1 - error; 0 - init; 1 - success)
+  templateName: require('templates/common/form'),
+  tagName: 'form',
 
-  init:function () {
+  init: function () {
     this._super();
     var thisForm = this;
     if (!this.fields.length)
@@ -46,7 +46,7 @@ App.Form = Em.View.extend({
         });
   },
 
-  getField:function (name) {
+  getField: function (name) {
     var field = false;
     $.each(this.fields, function () {
       if (this.get('name') == name) {
@@ -56,7 +56,7 @@ App.Form = Em.View.extend({
     return field;
   },
 
-  isValid:function () {
+  isValid: function () {
     var isValid = true;
     $.each(this.fields, function () {
       this.validate();
@@ -69,12 +69,12 @@ App.Form = Em.View.extend({
     return isValid;
   },
 
-  isObjectNew:function () {
+  isObjectNew: function () {
     var object = this.get('object');
     return !(object instanceof DS.Model && object.get('id'));
   }.property("object"),
 
-  updateValues:function () {
+  updateValues: function () {
     var object = this.get('object');
     if (object instanceof Em.Object) {
       $.each(this.fields, function () {
@@ -89,16 +89,17 @@ App.Form = Em.View.extend({
   /**
    *
    */
-  getValues:function () {
+
+  getValues: function () {
     var values = {};
     $.each(this.fields, function () {
-      if(!(this.get('displayType') == 'password') && validator.empty(this.get('value'))) // if this is not empty password field
+      if (!(this.get('displayType') == 'password') && validator.empty(this.get('value'))) // if this is not empty password field
         values[this.get('name')] = this.get('value');
     });
     return values;
   },
 
-  clearValues:function () {
+  clearValues: function () {
     $.each(this.fields, function () {
       this.set('value', '');
     });
@@ -108,7 +109,7 @@ App.Form = Em.View.extend({
    * need to refactor for integration
    * @return {Boolean}
    */
-  save:function () {
+  save: function () {
     var thisForm = this;
     var object = this.get('object');
     if (!this.get('isObjectNew')) {
@@ -128,7 +129,7 @@ App.Form = Em.View.extend({
     return true;
   },
 
-  resultText:function () {
+  resultText: function () {
     var text = "";
     switch (this.get('result')) {
       case -1:
@@ -142,7 +143,7 @@ App.Form = Em.View.extend({
     return text;
   }.property('result'),
 
-  saveButtonText:function () {
+  saveButtonText: function () {
     return Em.I18n.t(this.get('i18nprefix') + (this.get('isObjectNew') ? "create" : "save"));
   }.property('isObjectNew')
 
@@ -153,24 +154,24 @@ App.Form = Em.View.extend({
 });
 
 App.FormField = Em.Object.extend({ // try to realize this as view
-  name:'',
-  displayName:'',
+  name: '',
+  displayName: '',
 //  defaultValue:'', NOT REALIZED YET
-  description:'',
-  disabled:false,
-  displayType:'string', // string, digits, number, directories, textarea, checkbox
-  disableRequiredOnPresent:false,
-  errorMessage:'',
-  form:false,
-  isRequired:true, // by default a config property is required
-  unit:'',
-  value:'',
+  description: '',
+  disabled: false,
+  displayType: 'string', // string, digits, number, directories, textarea, checkbox
+  disableRequiredOnPresent: false,
+  errorMessage: '',
+  form: false,
+  isRequired: true, // by default a config property is required
+  unit: '',
+  value: '',
 
-  isValid:function () {
+  isValid: function () {
     return this.get('errorMessage') === '';
   }.property('errorMessage'),
 
-  viewClass:function () {
+  viewClass: function () {
     var options = {};
     var element = Em.TextField;
     switch (this.get('displayType')) {
@@ -196,9 +197,9 @@ App.FormField = Em.Object.extend({ // try to realize this as view
     return element.extend(options);
   }.property('displayType'),
 
-  validate:function () {
+  validate: function () {
     var digitsRegex = /^\d+$/;
-    var numberRegex = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/;
+    var numberRegex = /^[-,+]?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/;
     var value = this.get('value');
     var isError = false;
     this.set('errorMessage', '');

+ 2 - 2
ambari-web/app/models/hosts.js

@@ -22,8 +22,8 @@ App.HostInfo = Ember.Object.extend({
   elementId: 'host',
   name: '',
   status: 'info',
-  cpu: '',
-  memory: '',
+  cpu: '2',
+  memory: '2',
   message: 'Information',
   progress: '0',
   barColor: 'progress-info',

+ 28 - 14
ambari-web/app/models/service_config.js

@@ -69,6 +69,9 @@ App.ServiceConfigProperty = Ember.Object.extend({
     this.set('value', this.get('defaultValue'));
     // TODO: remove mock data
     switch (this.get('name')) {
+      case 'datanode.hosts':
+        this.set('value', [ 'host0001.company.com', 'host0002.company.com', 'host0003.company.com' ]);
+        break;
       case 'mapred_local_dir':
         this.set('value', '/grid/0/hadoop/mapred\n/grid/1/hadoop/mapred\n');
         break;
@@ -87,18 +90,6 @@ App.ServiceConfigProperty = Ember.Object.extend({
       case 'dfs_data_dir':
         this.set('value', '/grid/0/hadoop/hdfs/data\n/grid/1/hadoop/hdfs/data\n');
         break;
-      case 'namenode.host':
-        this.set('value', 'namenode.company.com');
-        break;
-      case 'snamenode.host':
-        this.set('value', 'snamenode.company.com');
-        break;
-      case 'datanode.hosts':
-        this.set('value', [ 'host0001.company.com', 'host0002.company.com', 'host0003.company.com' ]);
-        break;
-      case 'jobtracker.host':
-        this.set('value', 'jobtracker.company.com');
-        break;
       case 'tasktracker.hosts':
         this.set('value', [ 'host0001.company.com', 'host0002.company.com', 'host0003.company.com' ]);
         break;
@@ -111,11 +102,34 @@ App.ServiceConfigProperty = Ember.Object.extend({
       case 'zookeeperserver.hosts':
         this.set('value', [ 'zk1.company.com', 'zk2.company.com', 'zk3.company.com' ]);
         break;
+    }
+  },
+
+  initialValue: function() {
+    var masterComponentHostsInDB = App.db.getMasterComponentHosts();
+    switch (this.get('name')) {
+      case 'namenode.host':
+        var temp = masterComponentHostsInDB.findProperty('component','NameNode');
+        console.log("this is temp: " + temp.hostName);
+        this.set('value', temp.hostName);
+        break;
+      case 'snamenode.host':
+        this.set('value', masterComponentHostsInDB.findProperty('component','SNameNode').hostName);
+        break;
+      case 'jobtracker.host':
+        this.set('value', masterComponentHostsInDB.findProperty('component','JobTracker').hostName);
+        break;
+      case 'hbasemaster.host':
+        this.set('value', masterComponentHostsInDB.findProperty('component','HBase Master').hostName);
+        break;
+      case 'zookeeperserver.hosts':
+        this.set('value', masterComponentHostsInDB.filterProperty('component','ZooKeeper').mapProperty('hostName'));
+        break;
       case 'hivemetastore.host':
-        this.set('value', 'hive.company.com');
+        this.set('value', masterComponentHostsInDB.findProperty('component','Hive Metastore').hostName);
         break;
       case 'oozieserver.host':
-        this.set('value', 'oozie.company.com');
+        this.set('value', masterComponentHostsInDB.findProperty('component','Oozie Server').hostName);
         break;
     }
   },

+ 18 - 2
ambari-web/app/router.js

@@ -15,10 +15,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 var App = require('app');
 App.Router = Em.Router.extend({
 
   enableLogging: true,
+  isFwdNavigation: true,
+
+  setNavigationFlow: function (step) {
+    var newStep = parseInt(step.slice(-1));
+    var previousStep = parseInt(this.getInstallerCurrentStep());
+    if (newStep >= previousStep) {
+      this.set('isFwdNavigation', true);
+    } else {
+      this.set('isFwdNavigation', false);
+    }
+  },
 
   setInstallerCurrentStep: function (currentStep, completed) {
     var loginName = this.getLoginName();
@@ -67,9 +79,13 @@ App.Router = Em.Router.extend({
   },
 
   // that works incorrectly
-  setUser: function(user){ App.db.setUser(user); },
+  setUser: function (user) {
+    App.db.setUser(user);
+  },
   // that works incorrectly
-  getUser: function(){ return App.db.getUser(); },
+  getUser: function () {
+    return App.db.getUser();
+  },
 
   login: function (loginName, user) {
     // TODO: this needs to be hooked up with server authentication

+ 10 - 8
ambari-web/app/routes/installer.js

@@ -45,15 +45,14 @@ module.exports = Em.Route.extend({
     route: '/step1',
     connectOutlets: function (router, context) {
       console.log('in installer.step1:connectOutlets');
+      router.setNavigationFlow('step1');
       router.setInstallerCurrentStep('1', false);
       router.get('installerController').connectOutlet('installerStep1');
     },
 
     next: function (router, context) {
-      console.log('In step1 transiting to step2');
       var result = router.get('installerStep1Controller').validateStep1();
       if (result === true) {
-        App.InstallerStep1View.remove;
         router.transitionTo('step2');
       } else {
         router.get('installerController').connectOutlet('installerStep1');
@@ -64,6 +63,7 @@ module.exports = Em.Route.extend({
   step2: Em.Route.extend({
     route: '/step2',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step2');
       router.setInstallerCurrentStep('2', false);
       router.get('installerController').connectOutlet('installerStep2');
     },
@@ -79,6 +79,7 @@ module.exports = Em.Route.extend({
   step3: Em.Route.extend({
     route: '/step3',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step3');
       router.setInstallerCurrentStep('3', false);
       router.get('installerController').connectOutlet('installerStep3');
     },
@@ -89,15 +90,12 @@ module.exports = Em.Route.extend({
   step4: Em.Route.extend({
     route: '/step4',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step4');
       router.setInstallerCurrentStep('4', false);
       router.get('installerController').connectOutlet('installerStep4');
     },
     back: Em.Router.transitionTo('step3'),
     next: function (router, context) {
-      // TODO:
-      // since the service selection could have changed, invalidate service configs
-      // this is a little aggressive and unfriendly - to be optimized later
-      router.set('installerStep7Controller.doInit', true);
       router.transitionTo('step5');
     }
   }),
@@ -105,6 +103,7 @@ module.exports = Em.Route.extend({
   step5: Em.Route.extend({
     route: '/step5',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step5');
       router.setInstallerCurrentStep('5', false);
       router.get('installerController').connectOutlet('installerStep5');
     },
@@ -115,6 +114,7 @@ module.exports = Em.Route.extend({
   step6: Em.Route.extend({
     route: '/step6',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step6');
       router.setInstallerCurrentStep('6', false);
       router.get('installerController').connectOutlet('installerStep6');
     },
@@ -125,8 +125,8 @@ module.exports = Em.Route.extend({
   step7: Em.Route.extend({
     route: '/step7',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step7');
       router.setInstallerCurrentStep('7', false);
-      router.get('installerStep7Controller').loadConfigs();
       router.get('installerController').connectOutlet('installerStep7');
     },
     back: Em.Router.transitionTo('step6'),
@@ -137,6 +137,7 @@ module.exports = Em.Route.extend({
     route: '/step8',
 
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step8');
       router.setInstallerCurrentStep('8', false);
       router.get('installerController').connectOutlet('installerStep8');
     },
@@ -147,6 +148,7 @@ module.exports = Em.Route.extend({
   step9: Em.Route.extend({
     route: '/step9',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step9');
       router.setInstallerCurrentStep('9', false);
       router.get('installerController').connectOutlet('installerStep9');
     },
@@ -157,10 +159,10 @@ module.exports = Em.Route.extend({
   step10: Em.Route.extend({
     route: '/step10',
     connectOutlets: function (router, context) {
+      router.setNavigationFlow('step10');
       router.setInstallerCurrentStep('10', false);
       router.get('installerController').connectOutlet('installerStep10');
     },
-
     back: Em.Router.transitionTo('step9'),
 
     complete: function (router, context) {

+ 10 - 10
ambari-web/app/templates/installer.hbs

@@ -25,16 +25,16 @@
           <div class="well">
             <ul class="nav nav-pills nav-stacked">
               <li class="nav-header">{{t installer.header}}</li>
-              <li {{bindAttr class="isStep1:active"}}><a {{action gotoStep1}}>{{t installer.step1.header}}</a></li>
-              <li {{bindAttr class="isStep2:active"}}><a {{action gotoStep2}}>{{t installer.step2.header}}</a></li>
-              <li {{bindAttr class="isStep3:active"}}><a {{action gotoStep3}}>{{t installer.step3.header}}</a></li>
-              <li {{bindAttr class="isStep4:active"}}><a {{action gotoStep4}}>{{t installer.step4.header}}</a></li>
-              <li {{bindAttr class="isStep5:active"}}><a {{action gotoStep5}}>{{t installer.step5.header}}</a></li>
-              <li {{bindAttr class="isStep6:active"}}><a {{action gotoStep6}}>{{t installer.step6.header}}</a></li>
-              <li {{bindAttr class="isStep7:active"}}><a {{action gotoStep7}}>{{t installer.step7.header}}</a></li>
-              <li {{bindAttr class="isStep8:active"}}><a {{action gotoStep8}}>{{t installer.step8.header}}</a></li>
-              <li {{bindAttr class="isStep9:active"}}><a {{action gotoStep9}}>{{t installer.step9.header}}</a></li>
-              <li {{bindAttr class="isStep10:active"}}><a {{action gotoStep10}}>{{t installer.step10.header}}</a></li>
+              <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a {{action gotoStep1 target="controller"}}>{{t installer.step1.header}}</a></li>
+              <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a {{action gotoStep2 target="controller"}}>{{t installer.step2.header}}</a></li>
+              <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a {{action gotoStep3 target="controller"}}>{{t installer.step3.header}}</a></li>
+              <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a {{action gotoStep4 target="controller"}}>{{t installer.step4.header}}</a></li>
+              <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a {{action gotoStep5 target="controller"}}>{{t installer.step5.header}}</a></li>
+              <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a {{action gotoStep6 target="controller"}}>{{t installer.step6.header}}</a></li>
+              <li {{bindAttr class="isStep7:active view.isStep7Disabled:disabled"}}><a {{action gotoStep7 target="controller"}}>{{t installer.step7.header}}</a></li>
+              <li {{bindAttr class="isStep8:active view.isStep8Disabled:disabled"}}><a {{action gotoStep8 target="controller"}}>{{t installer.step8.header}}</a></li>
+              <li {{bindAttr class="isStep9:active view.isStep9Disabled:disabled"}}><a {{action gotoStep9 target="controller"}}>{{t installer.step9.header}}</a></li>
+              <li {{bindAttr class="isStep10:active view.isStep10Disabled:disabled"}}><a {{action gotoStep10 target="controller"}}>{{t installer.step10.header}}</a></li>
             </ul>
           </div>
         </div>

+ 4 - 3
ambari-web/app/templates/installer/step2.hbs

@@ -21,10 +21,10 @@
 <h5 {{bindAttr class="hostManageErr:text-error"}}>{{t installer.step2.targetHosts}}</h5>
 
 <div {{bindAttr class="hostNameErrMsg:error :control-group"}}>
-  <p>{{t installer.step2.targetHosts.info}}.  Or use
+  <p>{{t installer.step2.targetHosts.info}}. Or use
     <a href="javascript:void(null)"
        rel="popover"
-       {{translateAttr title="installer.step2.hostPattern.tooltip.title" data-content="installer.step2.hostPattern.tooltip.content"}}>
+      {{translateAttr title="installer.step2.hostPattern.tooltip.title" data-content="installer.step2.hostPattern.tooltip.content"}}>
       {{t installer.step2.hostPattern.tooltip.title}}
     </a>
   </p>
@@ -44,7 +44,8 @@
       <div class="controls">
         {{view Ember.TextArea class="span6" rows="4" placeholder="ssh private key" valueBinding="sshKey"}}
         {{#if sshKeyNullErr}}
-        <span class="help-inline">{{t installer.step2.sshKey.error.required}}</span>
+        <span
+          class="help-inline">{{t installer.step2.sshKey.error.required}}</span>
         {{/if}}
       </div>
     </div>

+ 1 - 1
ambari-web/app/templates/installer/step4.hbs

@@ -51,6 +51,6 @@
 
   <div class="btn-area">
     <a class="btn pull-left" {{action back}}>&larr; Back</a>
-    <a class="btn btn-success pull-right" {{action submit target="controller"}}>Next &rarr;</a>
+    <a class="btn btn-success pull-right" {{action proceed target="controller"}}>Next &rarr;</a>
   </div>
 </div>

+ 41 - 1
ambari-web/app/views/installer.js

@@ -21,6 +21,46 @@ var App = require('app');
 
 App.InstallerView = Em.View.extend({
 
-    templateName: require('templates/installer')
+  templateName: require('templates/installer'),
+
+  isStep1Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',1).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep2Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',2).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep3Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',3).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep4Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',4).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep5Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',5).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep6Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',6).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep7Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',7).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep8Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',8).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep9Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',9).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep10Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',10).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable()
 
 });

+ 2 - 0
ambari-web/app/views/installer/step2_view.js

@@ -25,7 +25,9 @@ App.InstallerStep2View = Em.View.extend({
 
   didInsertElement: function () {
     $("[rel=popover]").popover({'placement': 'right', 'trigger': 'hover'});
+    this.get('controller').loadStep();
   }
+
 });
 
 

+ 1 - 3
ambari-web/app/views/installer/step3_view.js

@@ -26,9 +26,7 @@ App.InstallerStep3View = Em.View.extend({
 
   didInsertElement: function () {
     var controller = this.get('controller');
-    var hosts = controller.loadHosts();
-    controller.renderHosts(hosts);
-    controller.startBootstrap();
+    controller.loadStep();
   }
 });
 

+ 6 - 1
ambari-web/app/views/installer/step4_view.js

@@ -21,6 +21,11 @@ var App = require('app');
 
 App.InstallerStep4View = Em.View.extend({
 
-  templateName: require('templates/installer/step4')
+  templateName: require('templates/installer/step4'),
+
+  didInsertElement: function () {
+    var controller = this.get('controller');
+    controller.loadStep();
+  }
 
 });

+ 6 - 1
ambari-web/app/views/installer/step7_view.js

@@ -21,7 +21,12 @@ var App = require('app');
 
 App.InstallerStep7View = Em.View.extend({
 
-  templateName: require('templates/installer/step7')
+  templateName: require('templates/installer/step7'),
+
+  didInsertElement: function () {
+    var controller = this.get('controller');
+    controller.loadStep();
+  }
 
 });
 

+ 10 - 11
ambari-web/app/views/installer/step9_view.js

@@ -28,6 +28,7 @@ App.InstallerStep9View = Em.View.extend({
 
   didInsertElement: function () {
     var controller = this.get('controller');
+    controller.loadStep();
     controller.clear();
     var hosts = controller.loadHosts();
     controller.renderHosts(hosts);
@@ -43,10 +44,8 @@ App.InstallerStep9View = Em.View.extend({
 
   onStatus: function () {
     if (this.get('controller.status') === 'info') {
-      console.log('TRACE: Inside info view step9');
       this.set('barColor', 'progress-info');
     } else if (this.get('controller.status') === 'warning') {
-      console.log('TRACE: Inside warning view step9');
       this.set('barColor', 'progress-warning');
     } else if (this.get('controller.status') === 'failed') {
       this.set('barColor', 'progress-danger');
@@ -89,29 +88,29 @@ App.HostStatusView = Em.View.extend({
     }
   }.observes('obj.status'),
 
-  isFailed: function() {
-    if(this.get('controller.isStepCompleted') === true && this.get('obj.status') === 'failed') {
+  isFailed: function () {
+    if (this.get('controller.isStepCompleted') === true && this.get('obj.status') === 'failed') {
       return true;
     } else {
       return false;
     }
-  }.property('controller.isStepCompleted','controller.status'),
+  }.property('controller.isStepCompleted', 'controller.status'),
 
-  isSuccess: function() {
-    if(this.get('controller.isStepCompleted') === true && this.get('obj.status') === 'success') {
+  isSuccess: function () {
+    if (this.get('controller.isStepCompleted') === true && this.get('obj.status') === 'success') {
       return true;
     } else {
       return false;
     }
-  }.property('controller.isStepCompleted','controller.status'),
+  }.property('controller.isStepCompleted', 'controller.status'),
 
-  isWarning: function() {
-    if(this.get('controller.isStepCompleted') === true && this.get('obj.status') === 'warning') {
+  isWarning: function () {
+    if (this.get('controller.isStepCompleted') === true && this.get('obj.status') === 'warning') {
       return true;
     } else {
       return false;
     }
-  }.property('controller.isStepCompleted','controller.status')
+  }.property('controller.isStepCompleted', 'controller.status')
 
 });
 

+ 5 - 0
ambari-web/test/installer/step4_test.js

@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+var Ember = require('ember');
 var App = require('app');
 require('controllers/installer/step4_controller');
 
@@ -25,6 +26,10 @@ describe('App.InstallerStep4Controller', function () {
   var OPTIONAL_SERVICES = ['MAPREDUCE', 'NAGIOS', 'GANGLIA', 'OOZIE', 'HIVE', 'HBASE', 'PIG', 'SQOOP', 'ZOOKEEPER', 'HCATALOG'];
 
   var controller = App.InstallerStep4Controller.create();
+  controller.rawContent.forEach(function(item){
+    item.isSelected = true;
+    controller.pushObject(Ember.Object.create(item));
+    });
 
   describe('#selectMinimum()', function () {
     it('should set isSelected is false on all non-default services and isSelected is true on all default services', function() {

+ 44 - 13
ambari-web/test/installer/step5_test.js

@@ -16,12 +16,35 @@
  * limitations under the License.
  */
 
+var Ember = require('ember');
 var App = require('app');
 require('controllers/installer/step5_controller');
 
 describe('App.InstallerStep5Controller', function () {
-
   var controller = App.InstallerStep5Controller.create();
+  controller.get("selectedServices").pushObject({service_name: 'ZOOKEEPER'});
+  var cpu = 2, memory = 4;
+  var HOST = ['host1', 'host2', 'host3', 'host4', 'host5'];
+  var hosts = [];
+  HOST.forEach(function (_host) {
+    controller.get('hosts').pushObject(Ember.Object.create({
+      host_name: _host,
+      cpu: cpu,
+      memory: memory
+    }));
+  });
+
+  var componentObj = Ember.Object.create({
+    component_name: 'ZooKeeper',
+    selectedHost: 'host2', // call the method that plays selectNode algorithm or fetches from server
+    availableHosts: []
+  });
+  componentObj.set('availableHosts', controller.get('hosts').slice(0));
+  componentObj.set('zId', 1);
+  componentObj.set("showAddControl", true);
+  componentObj.set("showRemoveControl", false);
+  controller.get("selectedServicesMasters").pushObject(componentObj);
+
 
   describe('#getAvailableHosts()', function () {
     it('should generate available hosts for a new zookeeper service', function () {
@@ -48,13 +71,18 @@ describe('App.InstallerStep5Controller', function () {
   })
 
   describe('#assignHostToMaster()', function () {
-    it('should assign the selected host to the master service', function () {
+    it('should assign the selected host to the non-ZooKeeper master service', function () {
       //test non-zookeeper master
       var SERVICE_MASTER = "NameNode",
         HOST = "host4", ZID, status;
-
+      var nonZookeeperObj = Ember.Object.create({
+        component_name: SERVICE_MASTER,
+        selectedHost: HOST, // call the method that plays selectNode algorithm or fetches from server
+        availableHosts: []
+      });
+      controller.get("selectedServicesMasters").pushObject(nonZookeeperObj);
       controller.assignHostToMaster(SERVICE_MASTER, HOST);
-      expect(controller.get("selectedServicesMasters").findProperty("component_name", "NameNode").get("selectedHost")).to.equal(HOST);
+      expect(controller.get("selectedServicesMasters").findProperty("component_name", SERVICE_MASTER).get("selectedHost")).to.equal(HOST);
     })
 
     it('should assign the selected host to the ZooKeeper master service', function () {
@@ -71,9 +99,10 @@ describe('App.InstallerStep5Controller', function () {
   })
 
   describe('#addZookeepers()', function () {
+
     it('should add a new ZooKeeper', function () {
       var newLength = 0;
-      if (controller.get("selectedServices").mapProperty("service_name").contains("ZooKeeper")
+      if (controller.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")
         && controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").get("length") < controller.get("hosts.length")) {
         newLength = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").get("length");
         controller.addZookeepers();
@@ -82,24 +111,26 @@ describe('App.InstallerStep5Controller', function () {
     })
 
     it('should add ZooKeepers up to the number of hosts', function () {
-      var currentZooKeepers = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper"),
+
+      var currentZooKeepers = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").length,
         success = true;
 
       //add ZooKeepers as long as possible
       if (currentZooKeepers) {
+
         while (success) {
           success = controller.addZookeepers();
         }
-
-        expect(controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").get("length")).to.equal(controller.get("hosts.length"));
+        var services = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
+        var length = services.length;
+        expect(controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").length).to.equal(controller.get("hosts.length"));
       }
     })
   })
 
   describe('#removeZookeepers()', function () {
     it('should remove a ZooKeeper', function () {
-      var newLength = 0;
-      if (controller.get("selectedServices").mapProperty("service_name").contains("ZooKeeper")) {
+      if (controller.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")) {
         if (controller.addZookeepers()) {
           newLength = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").get("length");
           controller.removeZookeepers(2);
@@ -109,15 +140,14 @@ describe('App.InstallerStep5Controller', function () {
     })
 
     it('should fail to remove a ZooKeeper if there is only 1', function () {
-      var currentZooKeepers = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper"),
+      var currentZooKeepers = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").length,
         success = true;
-
       //remove ZooKeepers as long as possible
+
       if (currentZooKeepers) {
         while (success) {
           success = controller.removeZookeepers(controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").get("lastObject.zId"));
         }
-
         expect(controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").get("length")).to.equal(1);
       }
     })
@@ -125,6 +155,7 @@ describe('App.InstallerStep5Controller', function () {
   })
 
   describe('#rebalanceZookeeperHosts()', function () {
+
     it('should rebalance hosts for ZooKeeper', function () {
       //assign a host to a zookeeper and then rebalance the available hosts for the other zookeepers
       var zookeepers = controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper"),

+ 94 - 81
ambari-web/test/installer/step6_test.js

@@ -23,118 +23,131 @@ require('controllers/installer/step6_controller');
 describe('App.InstallerStep6Controller', function () {
 
   var HOSTS = [ 'host1', 'host2', 'host3', 'host4' ];
-  App.InstallerStep6Controller.rawHosts = HOSTS;
+  //App.InstallerStep6Controller.set.rawHosts = HOSTS;
   var controller = App.InstallerStep6Controller.create();
+  controller.set('showHbase', false);
+  HOSTS.forEach(function (_hostName) {
+    controller.get('hosts').pushObject(Ember.Object.create({
+      hostname: _hostName,
+      isDataNode: true,
+      isTaskTracker: true,
+      isRegionServer: true
+    }));
+  });
+
 
-  describe('#selectAllDataNodes()', function () {
-    it('should set isDataNode to true on all hosts', function() {
-      controller.selectAllDataNodes();
-      expect(controller.get('hosts').everyProperty('isDataNode', true)).to.equal(true);
-    })
-  })
 
-  describe('#selectAllTaskTrackers()', function () {
-    it('should set isTaskTracker to true on all hosts', function() {
-      controller.selectAllTaskTrackers();
-      expect(controller.get('hosts').everyProperty('isTaskTracker', true)).to.equal(true);
-    })
+describe('#selectAllDataNodes()', function () {
+  controller.get('hosts').setEach('isDataNode', false);
+
+  it('should set isDataNode to true on all hosts', function () {
+    controller.selectAllDataNodes();
+    expect(controller.get('hosts').everyProperty('isDataNode', true)).to.equal(true);
   })
+})
 
-  describe('#selectAllRegionServers()', function () {
-    it('should set isRegionServer to true on all hosts', function() {
-      controller.selectAllRegionServers();
-      expect(controller.get('hosts').everyProperty('isRegionServer', true)).to.equal(true);
-    })
+describe('#selectAllTaskTrackers()', function () {
+  it('should set isTaskTracker to true on all hosts', function () {
+    controller.selectAllTaskTrackers();
+    expect(controller.get('hosts').everyProperty('isTaskTracker', true)).to.equal(true);
   })
+})
 
-  describe('#isAllDataNodes()', function () {
+describe('#selectAllRegionServers()', function () {
+  it('should set isRegionServer to true on all hosts', function () {
+    controller.selectAllRegionServers();
+    expect(controller.get('hosts').everyProperty('isRegionServer', true)).to.equal(true);
+  })
+})
 
-    beforeEach(function() {
-      controller.get('hosts').setEach('isDataNode', true);
-    })
+describe('#isAllDataNodes()', function () {
 
-    it('should return true if isDataNode is true for all services', function() {
-      expect(controller.get('isAllDataNodes')).to.equal(true);
-    })
+  beforeEach(function () {
+    controller.get('hosts').setEach('isDataNode', true);
+  })
 
-    it('should return false if isDataNode is false for one host', function() {
-      controller.get('hosts')[0].set('isDataNode', false);
-      expect(controller.get('isAllDataNodes')).to.equal(false);
-    })
+  it('should return true if isDataNode is true for all services', function () {
+    expect(controller.get('isAllDataNodes')).to.equal(true);
   })
 
-  describe('#isAllTaskTrackers()', function () {
+  it('should return false if isDataNode is false for one host', function () {
+    controller.get('hosts')[0].set('isDataNode', false);
+    expect(controller.get('isAllDataNodes')).to.equal(false);
+  })
+})
 
-    beforeEach(function() {
-      controller.get('hosts').setEach('isTaskTracker', true);
-    })
+describe('#isAllTaskTrackers()', function () {
 
-    it('should return true if isTaskTracker is true for all hosts', function() {
-      expect(controller.get('isAllTaskTrackers')).to.equal(true);
-    })
+  beforeEach(function () {
+    controller.get('hosts').setEach('isTaskTracker', true);
+  })
 
-    it('should return false if isTaskTracker is false for one host', function() {
-      controller.get('hosts')[0].set('isTaskTracker', false);
-      expect(controller.get('isAllTaskTrackers')).to.equal(false);
-    })
+  it('should return true if isTaskTracker is true for all hosts', function () {
+    expect(controller.get('isAllTaskTrackers')).to.equal(true);
+  })
 
+  it('should return false if isTaskTracker is false for one host', function () {
+    controller.get('hosts')[0].set('isTaskTracker', false);
+    expect(controller.get('isAllTaskTrackers')).to.equal(false);
   })
 
-  describe('#isAllRegionServers()', function () {
+})
 
-    beforeEach(function() {
-      controller.get('hosts').setEach('isRegionServer', true);
-    });
+describe('#isAllRegionServers()', function () {
 
-    it('should return true if isRegionServer is true for all hosts', function() {
-      expect(controller.get('isAllRegionServers')).to.equal(true);
-    })
+  beforeEach(function () {
+    controller.get('hosts').setEach('isRegionServer', true);
+  });
 
-    it('should return false if isRegionServer is false for one host', function() {
-      controller.get('hosts')[0].set('isRegionServer', false);
-      expect(controller.get('isAllRegionServers')).to.equal(false);
-    })
+  it('should return true if isRegionServer is true for all hosts', function () {
+    expect(controller.get('isAllRegionServers')).to.equal(true);
+  })
 
+  it('should return false if isRegionServer is false for one host', function () {
+    controller.get('hosts')[0].set('isRegionServer', false);
+    expect(controller.get('isAllRegionServers')).to.equal(false);
   })
 
-  describe('#validate()', function () {
+})
 
-    beforeEach(function() {
-      controller.get('hosts').setEach('isDataNode', true);
-      controller.get('hosts').setEach('isTaskTracker', true);
-      controller.get('hosts').setEach('isRegionServer', true);
-    });
+describe('#validate()', function () {
 
-    it('should return false if isDataNode is false for all hosts', function() {
-      controller.get('hosts').setEach('isDataNode', false);
-      expect(controller.validate()).to.equal(false);
-    })
+  beforeEach(function () {
+    controller.get('hosts').setEach('isDataNode', true);
+    controller.get('hosts').setEach('isTaskTracker', true);
+    controller.get('hosts').setEach('isRegionServer', true);
+  });
 
-    it('should return false if isTaskTracker is false for all hosts', function() {
-      controller.get('hosts').setEach('isTaskTracker', false);
-      expect(controller.validate()).to.equal(false);
-    })
+  it('should return false if isDataNode is false for all hosts', function () {
+    controller.get('hosts').setEach('isDataNode', false);
+    expect(controller.validate()).to.equal(false);
+  })
 
-    it('should return false if isRegionServer is false for all hosts', function() {
-      controller.get('hosts').setEach('isRegionServer', false);
-      expect(controller.validate()).to.equal(false);
-    })
+  it('should return false if isTaskTracker is false for all hosts', function () {
+    controller.get('hosts').setEach('isTaskTracker', false);
+    expect(controller.validate()).to.equal(false);
+  })
 
-    it('should return true if isDataNode, isTaskTracker, and isRegionServer is true for all hosts', function() {
-      expect(controller.validate()).to.equal(true);
-    })
+  it('should return false if isRegionServer is false for all hosts', function () {
+    controller.get('hosts').setEach('isRegionServer', false);
+    expect(controller.validate()).to.equal(false);
+  })
 
-    it('should return true if isDataNode, isTaskTracker, and isRegionServer is true for only one host', function() {
-      controller.get('hosts').setEach('isDataNode', false);
-      controller.get('hosts').setEach('isTaskTracker', false);
-      controller.get('hosts').setEach('isRegionServer', false);
-      var host = controller.get('hosts')[0];
-      host.set('isDataNode', true);
-      host.set('isTaskTracker', true);
-      host.set('isRegionServer', true);
-      expect(controller.validate()).to.equal(true);
-    })
+  it('should return true if isDataNode, isTaskTracker, and isRegionServer is true for all hosts', function () {
+    expect(controller.validate()).to.equal(true);
+  })
 
+  it('should return true if isDataNode, isTaskTracker, and isRegionServer is true for only one host', function () {
+    controller.get('hosts').setEach('isDataNode', false);
+    controller.get('hosts').setEach('isTaskTracker', false);
+    controller.get('hosts').setEach('isRegionServer', false);
+    var host = controller.get('hosts')[0];
+    host.set('isDataNode', true);
+    host.set('isTaskTracker', true);
+    host.set('isRegionServer', true);
+    expect(controller.validate()).to.equal(true);
   })
 
+})
+
 })

+ 0 - 11
ambari-web/test/installer/step7_test.js

@@ -21,15 +21,4 @@ require('controllers/installer/step7_controller');
 
 describe('App.InstallerStep7Controller', function () {
 
-  /*
-  describe('#validateStep1()', function () {
-    it('should return false and sets invalidClusterName to true if cluster name is empty', function () {
-      var controller = App.InstallerStep1Controller.create();
-      controller.set('clusterName', '');
-      expect(controller.validateStep1()).to.equal(false);
-      expect(controller.get('invalidClusterName')).to.equal(true);
-    })
-  })
-  */
-
 })