瀏覽代碼

AMBARI-941. More refactoring of Wizards in Ambari Web. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1403142 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 年之前
父節點
當前提交
0ee0fb6760
共有 47 個文件被更改,包括 761 次插入1947 次删除
  1. 2 0
      AMBARI-666-CHANGES.txt
  2. 2 7
      ambari-web/app/controllers.js
  3. 87 13
      ambari-web/app/controllers/installer.js
  4. 0 81
      ambari-web/app/controllers/installer/step1_controller.js
  5. 0 158
      ambari-web/app/controllers/installer/step4_controller.js
  6. 0 605
      ambari-web/app/controllers/installer/step5_controller.js
  7. 0 321
      ambari-web/app/controllers/installer/step6_controller.js
  8. 11 34
      ambari-web/app/controllers/login_controller.js
  9. 89 13
      ambari-web/app/controllers/main/host/add_controller.js
  10. 67 1
      ambari-web/app/controllers/main/host/details.js
  11. 2 2
      ambari-web/app/controllers/wizard/step10_controller.js
  12. 7 4
      ambari-web/app/controllers/wizard/step5_controller.js
  13. 86 18
      ambari-web/app/controllers/wizard/step6_controller.js
  14. 7 5
      ambari-web/app/models/service.js
  15. 36 30
      ambari-web/app/router.js
  16. 25 11
      ambari-web/app/routes/add_host_routes.js
  17. 60 18
      ambari-web/app/routes/installer.js
  18. 105 100
      ambari-web/app/styles/application.less
  19. 0 42
      ambari-web/app/templates/installer/step1.hbs
  20. 0 56
      ambari-web/app/templates/installer/step4.hbs
  21. 0 76
      ambari-web/app/templates/installer/step5.hbs
  22. 0 81
      ambari-web/app/templates/installer/step6.hbs
  23. 1 1
      ambari-web/app/templates/main/dashboard/service/hbase.hbs
  24. 1 1
      ambari-web/app/templates/main/dashboard/service/hive.hbs
  25. 1 1
      ambari-web/app/templates/main/dashboard/service/mapreduce.hbs
  26. 1 1
      ambari-web/app/templates/main/dashboard/service/oozie.hbs
  27. 1 1
      ambari-web/app/templates/main/dashboard/service/zookeeper.hbs
  28. 4 4
      ambari-web/app/templates/main/host.hbs
  29. 2 2
      ambari-web/app/templates/main/host/summary.hbs
  30. 5 5
      ambari-web/app/templates/main/menu_item.hbs
  31. 1 1
      ambari-web/app/templates/wizard/step1.hbs
  32. 0 0
      ambari-web/app/templates/wizard/step10.hbs
  33. 16 2
      ambari-web/app/templates/wizard/step6.hbs
  34. 78 0
      ambari-web/app/utils/base64.js
  35. 1 5
      ambari-web/app/views.js
  36. 0 41
      ambari-web/app/views/installer/step1_view.js
  37. 0 31
      ambari-web/app/views/installer/step4_view.js
  38. 0 74
      ambari-web/app/views/installer/step5_view.js
  39. 0 80
      ambari-web/app/views/installer/step6_view.js
  40. 2 2
      ambari-web/app/views/main/admin/menu.js
  41. 2 2
      ambari-web/app/views/main/charts/menu.js
  42. 2 2
      ambari-web/app/views/main/host/menu.js
  43. 7 7
      ambari-web/app/views/main/menu.js
  44. 2 3
      ambari-web/app/views/main/service/info/menu.js
  45. 2 2
      ambari-web/app/views/wizard/step10_view.js
  46. 6 3
      ambari-web/app/views/wizard/step5_view.js
  47. 40 0
      ambari-web/app/views/wizard/step6_view.js

+ 2 - 0
AMBARI-666-CHANGES.txt

@@ -362,6 +362,8 @@ AMBARI-666 branch (unreleased changes)
 
 
   IMPROVEMENTS
   IMPROVEMENTS
 
 
+  AMBARI-941. More refactoring of Wizards in Ambari Web. (yusaku)
+
   AMBARI-919. Partial refactoring and consolidation of code for various
   AMBARI-919. Partial refactoring and consolidation of code for various
   wizards. (yusaku)
   wizards. (yusaku)
 
 

+ 2 - 7
ambari-web/app/controllers.js

@@ -22,14 +22,8 @@
 require('controllers/application');
 require('controllers/application');
 require('controllers/login_controller');
 require('controllers/login_controller');
 require('controllers/installer');
 require('controllers/installer');
-require('controllers/installer/step1_controller');
 require('controllers/installer/step2_controller');
 require('controllers/installer/step2_controller');
 require('controllers/installer/step3_controller');
 require('controllers/installer/step3_controller');
-require('controllers/installer/step4_controller');
-require('controllers/installer/step6_controller');
-require('controllers/installer/step5_controller');
-require('controllers/installer/step6_controller');
-require('controllers/installer/step10_controller');
 require('controllers/main');
 require('controllers/main');
 require('controllers/main/admin');
 require('controllers/main/admin');
 require('controllers/main/admin/item');
 require('controllers/main/admin/item');
@@ -64,4 +58,5 @@ require('controllers/wizard/step5_controller');
 require('controllers/wizard/step6_controller');
 require('controllers/wizard/step6_controller');
 require('controllers/wizard/step7_controller');
 require('controllers/wizard/step7_controller');
 require('controllers/wizard/step8_controller');
 require('controllers/wizard/step8_controller');
-require('controllers/wizard/step9_controller');
+require('controllers/wizard/step9_controller');
+require('controllers/wizard/step10_controller');

+ 87 - 13
ambari-web/app/controllers/installer.js

@@ -203,24 +203,26 @@ App.InstallerController = Em.Controller.extend({
   },
   },
 
 
   content: Em.Object.create({
   content: Em.Object.create({
-    cluster: {},
-    hosts: {},
-    services: {},
-    hostsInfo: {},
-    slaveComponentHosts: {},
-    hostSlaveComponents: {},
-    masterComponentHosts: {},
-    serviceConfigProperties: {}
+    cluster: null,
+    hosts: null,
+    services: null,
+    hostsInfo: null,
+    slaveComponentHosts: null,
+    hostSlaveComponents: null,
+    masterComponentHosts: null,
+    hostToMasterComponent : null,
+    serviceConfigProperties: null
   }),
   }),
 
 
   /**
   /**
    * Load clusterInfo(step1) to model
    * Load clusterInfo(step1) to model
    */
    */
   loadClusterInfo: function () {
   loadClusterInfo: function () {
+    var cStatus = App.db.getClusterStatus() || {status: "", isCompleted: false};
     var cluster = {
     var cluster = {
-      name: App.db.getClusterName(),
-      status: App.db.getClusterStatus().status,
-      isCompleted: App.db.getClusterStatus().isCompleted
+      name: App.db.getClusterName() || "",
+      status: cStatus.status,
+      isCompleted: cStatus.isCompleted
     };
     };
     this.set('content.cluster', cluster);
     this.set('content.cluster', cluster);
 
 
@@ -470,6 +472,19 @@ App.InstallerController = Em.Controller.extend({
     console.log("installerController.saveComponentHosts: saved hosts ", masterComponentHosts);
     console.log("installerController.saveComponentHosts: saved hosts ", masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
+
+    var hosts = masterComponentHosts.mapProperty('hostName').uniq();
+    var hostsMasterServicesMapping = [];
+    hosts.forEach(function (_host) {
+      var componentsOnHost = masterComponentHosts.filterProperty('hostName', _host).mapProperty('component');
+      hostsMasterServicesMapping.push({
+        hostname: _host,
+        components: componentsOnHost
+      });
+    }, this);
+    console.log("installerController.setHostToMasterComponent: saved hosts ", hostsMasterServicesMapping);
+    App.db.setHostToMasterComponent(hostsMasterServicesMapping);
+    this.set('content.hostToMasterComponent', hostsMasterServicesMapping);
   },
   },
 
 
   /**
   /**
@@ -479,6 +494,10 @@ App.InstallerController = Em.Controller.extend({
     var masterComponentHosts = App.db.getMasterComponentHosts();
     var masterComponentHosts = App.db.getMasterComponentHosts();
     this.set("content.masterComponentHosts", masterComponentHosts);
     this.set("content.masterComponentHosts", masterComponentHosts);
     console.log("InstallerController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
     console.log("InstallerController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
+
+    var hostsMasterServicesMapping = App.db.getHostToMasterComponent();
+    this.set("content.hostToMasterComponent", hostsMasterServicesMapping);
+    console.log("InstallerController.loadHostToMasterComponent: loaded hosts ", hostsMasterServicesMapping);
   },
   },
 
 
   /**
   /**
@@ -497,6 +516,7 @@ App.InstallerController = Em.Controller.extend({
     var dataNodeHosts = [];
     var dataNodeHosts = [];
     var taskTrackerHosts = [];
     var taskTrackerHosts = [];
     var regionServerHosts = [];
     var regionServerHosts = [];
+    var clientHosts = [];
 
 
     hosts.forEach(function (host) {
     hosts.forEach(function (host) {
       if (host.get('isDataNode')) {
       if (host.get('isDataNode')) {
@@ -517,6 +537,12 @@ App.InstallerController = Em.Controller.extend({
           group: 'Default'
           group: 'Default'
         });
         });
       }
       }
+      if (host.get('isClient')) {
+        clientHosts.pushObject({
+          hostname: host.hostname,
+          group: 'Default'
+        });
+      }
     }, this);
     }, this);
 
 
     var slaveComponentHosts = [];
     var slaveComponentHosts = [];
@@ -539,6 +565,11 @@ App.InstallerController = Em.Controller.extend({
         hosts: regionServerHosts
         hosts: regionServerHosts
       });
       });
     }
     }
+    slaveComponentHosts.pushObject({
+      componentName: 'CLIENT',
+      displayName: 'client',
+      hosts: clientHosts
+    });
 
 
     App.db.setSlaveComponentHosts(slaveComponentHosts);
     App.db.setSlaveComponentHosts(slaveComponentHosts);
     this.set('content.slaveComponentHosts', slaveComponentHosts);
     this.set('content.slaveComponentHosts', slaveComponentHosts);
@@ -558,7 +589,7 @@ App.InstallerController = Em.Controller.extend({
   },
   },
 
 
   /**
   /**
-   * TODO:
+   * Save config properties
    * @param stepController Step7WizardController
    * @param stepController Step7WizardController
    */
    */
   saveServiceConfigProperties: function (stepController) {
   saveServiceConfigProperties: function (stepController) {
@@ -587,6 +618,47 @@ App.InstallerController = Em.Controller.extend({
     console.log("InstallerController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
     console.log("InstallerController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
   },
   },
 
 
+  /**
+   * Load information about hosts with clients components
+   */
+  loadClients: function(){
+    var clients = App.db.getClientsForSelectedServices();
+    this.set('content.clients', clients);
+    console.log("InstallerController.loadClients: loaded list ", clients);
+  },
+
+  /**
+   * Generate clients list for selected services and save it to model
+   * @param stepController step4WizardController
+   */
+  saveClients: function(stepController){
+    var clients = [];
+    var serviceComponents = require('data/service_components');
+
+    stepController.get('content').filterProperty('isSelected',true).forEach(function (_service) {
+      var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
+      if (client) {
+        clients.pushObject({
+          component_name: client.component_name,
+          display_name: client.display_name
+        });
+      }
+    }, this);
+
+    App.db.setClientsForSelectedServices(clients);
+    this.set('content.clients', clients);
+    console.log("InstallerController.saveClients: saved list ", clients);
+  },
+
+  /**
+   * Load HostToMasterComponent array
+   */
+  loadHostToMasterComponent: function(){
+    var list = App.db.getHostToMasterComponent();
+    this.set('content.hostToMasterComponent', list);
+    console.log("AddHostController.loadHostToMasterComponent: loaded list ", list);
+  },
+
   /**
   /**
    * List of statuses, what data is currently loaded
    * List of statuses, what data is currently loaded
    */
    */
@@ -612,12 +684,14 @@ App.InstallerController = Em.Controller.extend({
           //need to call it every time since we preload data in setInfoForStep9
           //need to call it every time since we preload data in setInfoForStep9
         this.loadClusterInfo();
         this.loadClusterInfo();
       case '8':
       case '8':
-        this.callLoadFuncOnce('loadClusterInfo');
+        this.loadClusterInfo();
       case '7':
       case '7':
         this.callLoadFuncOnce('loadServiceConfigProperties');
         this.callLoadFuncOnce('loadServiceConfigProperties');
       case '6':
       case '6':
         this.callLoadFuncOnce('loadMasterComponentHosts');
         this.callLoadFuncOnce('loadMasterComponentHosts');
         this.callLoadFuncOnce('loadSlaveComponentHosts');
         this.callLoadFuncOnce('loadSlaveComponentHosts');
+        this.callLoadFuncOnce('loadClients');
+        this.callLoadFuncOnce('loadHostToMasterComponent');
       case '5':
       case '5':
         this.callLoadFuncOnce('loadConfirmedHosts');
         this.callLoadFuncOnce('loadConfirmedHosts');
       case '4':
       case '4':

+ 0 - 81
ambari-web/app/controllers/installer/step1_controller.js

@@ -1,81 +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.
- */
-
-var App = require('app');
-require('utils/db');
-
-App.InstallerStep1Controller = Em.Controller.extend({
-  name: 'installerStep1Controller',
-  content: [],
-  clusterName: '',
-  clusterNameError: '',
-  invalidClusterName: true,
-
-  /**
-   * Returns true if the cluster name is valid and stores it in localStorage.
-   * Returns false otherwise, and sets appropriate field error message.
-   */
-
-  clearStep: function() {
-    this.set('clusterName','');
-  },
-
-  loadStep: function () {
-    var clusterName;
-    console.log('The value of the cluster name is: ' + App.db.getClusterName());
-    if (App.db.getClusterName() !== undefined && App.db.getClusterName() !== true ) {
-      this.set('clusterName', App.db.getClusterName());
-    } else {
-      this.set('clusterNameError','');
-      this.set('invalidClusterName',true);
-    }
-  },
-
-  validateStep1: function () {
-    console.log('TRACE: Entering controller:InstallerStep1:validateStep1 function');
-    if (this.get('clusterName') == '') {
-      this.set('clusterNameError', Em.I18n.t('installer.step1.clusterName.error.required'));
-      this.set('invalidClusterName', true);
-      return false;
-    } else if (/\s/.test(this.get('clusterName'))) {
-      console.log('White spaces not allowed for cluster name');
-      this.set('clusterNameError', Em.I18n.t('installer.step1.clusterName.error.whitespaces'));
-      this.set('invalidClusterName', true);
-      return false;
-    } else if (/[^\w\s]/gi.test(this.get('clusterName'))) {
-      console.log('Special characters are not allowed for the cluster name');
-      this.set('clusterNameError', Em.I18n.t('installer.step1.clusterName.error.specialChar'));
-      this.set('invalidClusterName', true);
-      return false;
-    } else {
-      console.log('value of clusterName is: ' + this.get('clusterName'));
-      this.set('clusterNameError', '');
-      this.set('invalidClusterName', false);
-      return true;
-    }
-  }.observes('clusterName'),
-
-  submit: function () {
-    this.validateStep1();
-    if (this.get('clusterNameError') === '') {
-      App.db.setClusterName(this.get('clusterName'));
-      App.router.send('next');
-    }
-  }
-
-})

+ 0 - 158
ambari-web/app/controllers/installer/step4_controller.js

@@ -1,158 +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.
- */
-
-var App = require('app');
-var db = require('utils/db');
-
-App.InstallerStep4Controller = Em.ArrayController.extend({
-  name: 'installerStep4Controller',
-  rawContent: require('data/mock/services'),
-  content: [],
-
-  isAll: function () {
-    return this.everyProperty('isSelected', true);
-  }.property('@each.isSelected'),
-
-  isMinimum: function () {
-    return this.filterProperty('isDisabled', false).everyProperty('isSelected', false);
-  }.property('@each.isSelected'),
-
-  checkDependencies: function () {
-    var hbase = this.findProperty('serviceName', 'HBASE');
-    var zookeeper = this.findProperty('serviceName', 'ZOOKEEPER');
-    if (hbase && zookeeper) {
-      zookeeper.set('isSelected', hbase.get('isSelected'));
-    }
-    var hive = this.findProperty('serviceName', 'HIVE');
-    var hcatalog = this.findProperty('serviceName', 'HCATALOG');
-    if (hive && hcatalog) {
-      hcatalog.set('isSelected', hive.get('isSelected'));
-    }
-  }.observes('@each.isSelected'),
-
-  clearStep: function () {
-    this.clear();
-  },
-
-  loadStep: function () {
-    this.clearStep();
-    this.renderStep(this.loadServices());
-  },
-
-  loadServices: function () {
-    return db.getService();
-  },
-
-  renderStep: function (serviceInfo) {
-    serviceInfo.forEach(function (item) {
-      this.pushObject(Ember.Object.create(item));
-    }, this);
-  },
-
-  selectAll: function () {
-    this.setEach('isSelected', true);
-  },
-
-  selectMinimum: function () {
-    this.filterProperty('isDisabled', false).setEach('isSelected', false);
-  },
-
-  saveSelectedServiceNamesToDB: function () {
-    var serviceNames = [];
-    db.setService(this.get('content'));
-    this.filterProperty('isSelected', true).forEach(function (item) {
-      serviceNames.push(item.serviceName);
-    });
-    db.setSelectedServiceNames(serviceNames);
-  },
-
-  needToAddMapReduce: function () {
-    if (this.findProperty('serviceName', 'MAPREDUCE').get('isSelected') === false) {
-      var mapreduceDependentServices = this.filter(function (item) {
-        return ['PIG', 'OOZIE', 'HIVE'].contains(item.get('serviceName')) && item.get('isSelected', true);
-      });
-      return (mapreduceDependentServices.get('length') > 0);
-    } else {
-      return false;
-    }
-  },
-
-  setClientsForSelectedServices: function () {
-    var clients = [];
-    var serviceComponents = require('data/service_components');
-    db.getService().filterProperty('isSelected',true).forEach(function (_service) {
-      var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
-      if (client) {
-        clients.pushObject({
-          component_name: client.component_name,
-          display_name: client.display_name
-        });
-      }
-    }, this);
-    db.setClientsForSelectedServices(clients);
-  },
-
-  gangliaOrNagiosNotSelected: function () {
-    return (this.findProperty('serviceName', 'GANGLIA').get('isSelected') === false || this.findProperty('serviceName', 'NAGIOS').get('isSelected') === false);
-  },
-
-  submit: function () {
-    var self = this;
-    if (this.needToAddMapReduce()) {
-      App.ModalPopup.show({
-        header: Em.I18n.t('installer.step4.mapreduceCheck.popup.header'),
-        body: Em.I18n.t('installer.step4.mapreduceCheck.popup.body'),
-        onPrimary: function () {
-          self.findProperty('serviceName', 'MAPREDUCE').set('isSelected', true);
-          this.hide();
-          self.validateMonitoring();
-        },
-        onSecondary: function () {
-          this.hide();
-        }
-      });
-    } else {
-      self.validateMonitoring();
-    }
-  },
-
-  validateMonitoring: function () {
-    var self = this;
-    if (this.gangliaOrNagiosNotSelected()) {
-      App.ModalPopup.show({
-        header: Em.I18n.t('installer.step4.monitoringCheck.popup.header'),
-        body: Em.I18n.t('installer.step4.monitoringCheck.popup.body'),
-        onPrimary: function () {
-          this.hide();
-          self.proceed();
-        },
-        onSecondary: function () {
-          this.hide();
-        }
-      });
-    } else {
-      self.proceed();
-    }
-  },
-
-  proceed: function () {
-    this.saveSelectedServiceNamesToDB();
-    this.setClientsForSelectedServices();
-    App.router.send('next');
-  }
-})

+ 0 - 605
ambari-web/app/controllers/installer/step5_controller.js

@@ -1,605 +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.
- */
-
-var App = require('app');
-
-App.InstallerStep5Controller = Em.Controller.extend({
-  //properties
-  name: "installerStep5Controller",
-  hosts: [],
-  selectedServices: [],
-  selectedServicesMasters: [],
-  zId: 0,
-  components: require('data/service_components'),
-
-  /*
-   Below function retrieves host information from local storage
-   */
-
-  clearStep: function () {
-    this.set('hosts', []);
-    this.set('selectedServices', []);
-    this.set('selectedServicesMasters', []);
-    this.set('zId', 0);
-  },
-
-  loadStep: function () {
-    console.log("TRACE: Loading step5: Assign Masters");
-    this.clearStep();
-    this.renderHostInfo(this.loadHostInfo());
-    this.renderComponents(this.loadComponents(this.loadServices()));
-  },
-
-  loadHostInfo: function () {
-    var hostInfo = [];
-    hostInfo = App.db.getHosts();
-    var hosts = new Ember.Set();
-    for (var index in hostInfo) {
-      hosts.add(hostInfo[index]);
-      console.log("TRACE: host name is: " + hostInfo[index].name);
-    }
-    return hosts.filterProperty('bootStatus', 'success');
-  },
-
-  renderHostInfo: function (hostsInfo) {
-
-    //wrap the model data into
-
-    hostsInfo.forEach(function (_host) {
-      var hostObj = Ember.Object.create({
-        host_name: _host.name,
-        cpu: _host.cpu,
-        memory: _host.memory
-      });
-      console.log('pushing ' + hostObj.host_name);
-      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 serviceInfo = App.db.getService();
-    var services = serviceInfo.filterProperty('isSelected', true).mapProperty('serviceName');
-    services.forEach(function (item) {
-      console.log("TRACE: service name is: " + item);
-      this.get("selectedServices").pushObject(Ember.Object.create({service_name: item}));
-    }, this);
-
-    return services;
-
-  },
-
-  loadComponents: function (services) {
-    var components = new Ember.Set();
-    if (App.db.getMasterComponentHosts() === undefined) {
-      var masterComponents = this.components.filterProperty('isMaster', true);
-      for (var index in services) {
-        var componentInfo = masterComponents.filterProperty('service_name', services[index]);
-        componentInfo.forEach(function (_componentInfo) {
-          console.log("TRACE: master component name is: " + _componentInfo.display_name);
-          var componentObj = {};
-          componentObj.component_name = _componentInfo.display_name;
-          componentObj.selectedHost = this.selectHost(_componentInfo.component_name);   // call the method that plays selectNode algorithm or fetches from server
-          componentObj.availableHosts = [];
-          components.add(componentObj);
-        }, this);
-      }
-    } else {
-      var masterComponentHosts = App.db.getMasterComponentHosts();
-      masterComponentHosts.forEach(function (_masterComponentHost) {
-        var componentObj = {};
-        componentObj.component_name = _masterComponentHost.component;
-        componentObj.selectedHost = _masterComponentHost.hostName;   // call the method that plays selectNode algorithm or fetches from server
-        componentObj.availableHosts = [];
-        components.add(componentObj);
-      }, this);
-    }
-    return components;
-  },
-
-  getMasterComponents: function () {
-    return (this.get('selectedServicesMasters').slice(0));
-  },
-
-  renderComponents: function (masterComponents) {
-    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', parseInt(this.get('zId')) + 1);
-        zookeeperComponent = Ember.Object.create(item);
-        zookeeperComponent.set('zId', this.get('zId'));
-        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));
-        this.get("selectedServicesMasters").pushObject(componentObj);
-      }
-    }, this);
-  },
-
-  getKerberosServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else if (noOfHosts < 3) {
-      return hosts[1];
-    } else if (noOfHosts <= 5) {
-      return hosts[1];
-    } else if (noOfHosts <= 30) {
-      return hosts[3];
-    } else {
-      return hosts[5];
-    }
-  },
-
-  getNameNode: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    return hosts[0];
-  },
-
-  getSNameNode: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else {
-      return hosts[1];
-    }
-  },
-
-  getJobTracker: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else if (noOfHosts < 3) {
-      return hosts[1];
-    } else if (noOfHosts <= 5) {
-      return hosts[1];
-    } else if (noOfHosts <= 30) {
-      return hosts[1];
-    } else {
-      return hosts[2];
-    }
-  },
-
-  getHBaseMaster: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else if (noOfHosts < 3) {
-      return hosts[0];
-    } else if (noOfHosts <= 5) {
-      return hosts[0];
-    } else if (noOfHosts <= 30) {
-      return hosts[2];
-    } else {
-      return hosts[3];
-    }
-  },
-
-  getOozieServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else if (noOfHosts < 3) {
-      return hosts[1];
-    } else if (noOfHosts <= 5) {
-      return hosts[1];
-    } else if (noOfHosts <= 30) {
-      return hosts[2];
-    } else {
-      return hosts[3];
-    }
-  },
-
-  getOozieServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else if (noOfHosts < 3) {
-      return hosts[1];
-    } else if (noOfHosts <= 5) {
-      return hosts[1];
-    } else if (noOfHosts <= 30) {
-      return hosts[2];
-    } else {
-      return hosts[3];
-    }
-  },
-
-  getHiveServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else if (noOfHosts < 3) {
-      return hosts[1];
-    } else if (noOfHosts <= 5) {
-      return hosts[1];
-    } else if (noOfHosts <= 30) {
-      return hosts[2];
-    } else {
-      return hosts[4];
-    }
-  },
-
-  getTempletonServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts === 1) {
-      return hosts[0];
-    } else if (noOfHosts < 3) {
-      return hosts[1];
-    } else if (noOfHosts <= 5) {
-      return hosts[1];
-    } else if (noOfHosts <= 30) {
-      return hosts[2];
-    } else {
-      return hosts[4];
-    }
-  },
-
-  getZooKeeperServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    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) {
-    var hosts = this.get('hosts');
-    var hostnames = [];
-    var inc = 0;
-    hosts.forEach(function (_hostname) {
-      hostnames[inc] = _hostname.host_name;
-      inc++;
-    });
-    var hostExcAmbari = hostnames.without(location.hostname);
-    if (hostExcAmbari !== null || hostExcAmbari !== undefined || hostExcAmbari.length !== 0) {
-      return hostExcAmbari[0];
-    } else {
-      return hostnames[0];
-    }
-  },
-
-  getNagiosServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    var hostnames = [];
-    var inc = 0;
-    hosts.forEach(function (_hostname) {
-      hostnames[inc] = _hostname.host_name;
-      inc++;
-    });
-    var hostExcAmbari = hostnames.without(location.hostname);
-    if (hostExcAmbari !== null || hostExcAmbari !== undefined || hostExcAmbari.length !== 0) {
-      return hostExcAmbari[0];
-    } else {
-      return hostnames[0];
-    }
-  },
-
-  selectHost: function (componentName) {
-    var noOfHosts = this.get('hosts').length;
-    if (componentName === 'KERBEROS_SERVER') {
-      return this.getKerberosServer(noOfHosts).host_name;
-    } else if (componentName === 'NAMENODE') {
-      return this.getNameNode(noOfHosts).host_name;
-    } else if (componentName === 'SNAMENODE') {
-      return this.getSNameNode(noOfHosts).host_name;
-    } else if (componentName === 'JOBTRACKER') {
-      return this.getJobTracker(noOfHosts).host_name;
-    } else if (componentName === 'HBASE_MASTER') {
-      return this.getHBaseMaster(noOfHosts).host_name;
-    } else if (componentName === 'OOZIE_SERVER') {
-      return this.getOozieServer(noOfHosts).host_name;
-    } else if (componentName === 'HIVE_SERVER') {
-      return this.getHiveServer(noOfHosts).host_name;
-    } else if (componentName === 'TEMPLETON_SERVER') {
-      return this.getTempletonServer(noOfHosts).host_name;
-    } else if (componentName === 'ZOOKEEPER_SERVER') {
-      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') {
-      return this.getNagiosServer(noOfHosts);
-    }
-  },
-
-  masterHostMapping: function () {
-    var mapping = [], mappingObject, self = this, mappedHosts, hostObj, hostInfo;
-    //get the unique assigned hosts and find the master services assigned to them
-
-    mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq();
-
-    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({
-        host_name: item,
-        hostInfo: hostInfo,
-        masterServices: self.get("selectedServicesMasters").filterProperty("selectedHost", item)
-      });
-
-      mapping.pushObject(mappingObject);
-    }, this);
-
-    mapping.sort(this.sortHostsByName);
-
-    return mapping;
-
-  }.property("selectedServicesMasters.@each.selectedHost"),
-
-  remainingHosts: function () {
-    return (this.get("hosts.length") - this.get("masterHostMapping.length"));
-  }.property("selectedServicesMasters.@each.selectedHost"),
-
-  hasZookeeper: function () {
-    return this.selectedServices.findProperty("service_name", "ZooKeeper");
-  }.property("selectedServices"),
-
-  //methods
-  getAvailableHosts: function (componentName) {
-    var assignableHosts = [],
-      zookeeperHosts = null;
-
-    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 {
-      return this.get("hosts");
-    }
-  },
-
-  assignHostToMaster: function (masterService, selectedHost, zId) {
-    if (selectedHost && masterService) {
-      if ((masterService === "ZooKeeper") && zId) {
-        this.get('selectedServicesMasters').findProperty("zId", zId).set("selectedHost", selectedHost);
-        this.rebalanceZookeeperHosts();
-      }
-      else {
-        this.get('selectedServicesMasters').findProperty("component_name", masterService).set("selectedHost", selectedHost);
-      }
-
-    }
-  },
-
-  lastZooKeeper: function () {
-    var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
-    if (currentZooKeepers) {
-      var lastZooKeeper = currentZooKeepers.get("lastObject");
-      return lastZooKeeper;
-    } else {
-      return null;
-    }
-  },
-
-  addZookeepers: function () {
-    /*
-     *Logic: If ZooKeeper service is selected then there can be
-     * minimum 1 ZooKeeper master in total, and
-     * maximum 1 ZooKeeper on every host
-     */
-
-    var maxNumZooKeepers = this.get("hosts.length"),
-      currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper"),
-      newZookeeper = null,
-      zookeeperHosts = null,
-      suggestedHost = null,
-      i = 0,
-      lastZoo = null;
-    console.log('hosts legth is: ' + maxNumZooKeepers);
-    //work only if the Zookeeper service is selected in previous step
-    if (!this.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")) {
-      console.log('ALERT: Zookeeper service was not selected');
-      return false;
-    }
-
-    if (currentZooKeepers.get("length") < maxNumZooKeepers) {
-      console.log('currentZookeeper length less than maximum. Its: ' + currentZooKeepers.get("length"))
-      currentZooKeepers.set("lastObject.showAddControl", false);
-      if (currentZooKeepers.get("length") >= 1) {
-        currentZooKeepers.set("lastObject.showRemoveControl", true);
-      }
-
-      //create a new zookeeper based on an existing one
-      newZookeeper = Ember.Object.create({});
-      lastZoo = currentZooKeepers.get("lastObject");
-      newZookeeper.set("component_name", lastZoo.get("component_name"));
-      newZookeeper.set("selectedHost", lastZoo.get("selectedHost"));
-      newZookeeper.set("availableHosts", this.getAvailableHosts("ZooKeeper"));
-
-      if (currentZooKeepers.get("length") === (maxNumZooKeepers - 1)) {
-        newZookeeper.set("showAddControl", false);
-      } else {
-        newZookeeper.set("showAddControl", true);
-      }
-      newZookeeper.set("showRemoveControl", true);
-
-      //get recommended host for the new Zookeeper server
-      zookeeperHosts = currentZooKeepers.mapProperty("selectedHost").uniq();
-
-      for (i = 0; i < this.get("hosts.length"); i++) {
-        if (!(zookeeperHosts.contains(this.get("hosts")[i].get("host_name")))) {
-          suggestedHost = this.get("hosts")[i].get("host_name");
-          break;
-        }
-      }
-
-      newZookeeper.set("selectedHost", suggestedHost);
-      newZookeeper.set("zId", (currentZooKeepers.get("lastObject.zId") + 1));
-      this.set('zId', parseInt(this.get('zId')) + 1);
-
-      this.get("selectedServicesMasters").pushObject(newZookeeper);
-
-      this.rebalanceZookeeperHosts();
-
-      return true;
-    }
-    return false;//if no more zookeepers can be added
-  },
-
-  removeZookeepers: function (zId) {
-    var currentZooKeepers;
-
-    //work only if the Zookeeper service is selected in previous step
-    if (!this.get("selectedServices").mapProperty("service_name").contains("ZOOKEEPER")) {
-      return false;
-    }
-
-    currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
-
-    if (currentZooKeepers.get("length") > 1) {
-      this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(this.get("selectedServicesMasters").findProperty("zId", zId)));
-
-      currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
-      if (currentZooKeepers.get("length") < this.get("hosts.length")) {
-        currentZooKeepers.set("lastObject.showAddControl", true);
-      }
-
-      if (currentZooKeepers.get("length") === 1) {
-        currentZooKeepers.set("lastObject.showRemoveControl", false);
-      }
-      this.set('zId', parseInt(this.get('zId')) - 1);
-      this.rebalanceZookeeperHosts();
-
-      return true;
-    }
-
-    return false;
-
-  },
-
-  rebalanceZookeeperHosts: function () {
-    //for a zookeeper update the available hosts for the other zookeepers
-
-    var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper"),
-      zooHosts = currentZooKeepers.mapProperty("selectedHost"),
-      availableZooHosts = [],
-      preparedAvailableHosts = null;
-
-    //get all hosts available for zookeepers
-    this.get("hosts").forEach(function (item) {
-      if (!zooHosts.contains(item.get("host_name"))) {
-        availableZooHosts.pushObject(item);
-      }
-    }, this);
-
-    currentZooKeepers.forEach(function (item) {
-      preparedAvailableHosts = availableZooHosts.slice(0);
-      preparedAvailableHosts.pushObject(this.get("hosts").findProperty("host_name", item.get("selectedHost")))
-      preparedAvailableHosts.sort(this.sortHostsByConfig, this);
-      item.set("availableHosts", preparedAvailableHosts);
-    }, this);
-
-  },
-
-  sortHostsByConfig: function (a, b) {
-    //currently handling only total memory on the host
-    if (a.memory < b.memory) {
-      return 1;
-    }
-    else {
-      return -1;
-    }
-  },
-
-  sortHostsByName: function (a, b) {
-    if (a.host_name > b.host_name) {
-      return 1;
-    }
-    else {
-      return -1;
-    }
-  },
-
-  saveComponentHostsToDb: function () {
-    var obj = this.get('selectedServicesMasters');
-    var masterComponentHosts = [];
-    var inc = 0;
-    var array = [];
-    obj.forEach(function (_component) {
-      var hostArr = [];
-      masterComponentHosts.push({
-        component: _component.component_name,
-        hostName: _component.selectedHost
-      });
-    });
-
-    App.db.setMasterComponentHosts(masterComponentHosts);
-    this.saveHostToMasterComponents();
-
-  },
-
-  saveHostToMasterComponents: function () {
-    var hostMasterComponents = App.db.getMasterComponentHosts();
-    var hosts = hostMasterComponents.mapProperty('hostName').uniq();
-    var hostsMasterServicesMapping = [];
-    hosts.forEach(function (_host) {
-      var componentsOnHost = hostMasterComponents.filterProperty('hostName', _host).mapProperty('component');
-      hostsMasterServicesMapping.push({
-        hostname: _host,
-        components: componentsOnHost
-      });
-    }, this);
-    App.db.setHostToMasterComponent(hostsMasterServicesMapping);
-  },
-
-  submit: function () {
-    this.saveComponentHostsToDb();
-    App.router.send('next');
-  }
-
-});
-
-
-

+ 0 - 321
ambari-web/app/controllers/installer/step6_controller.js

@@ -1,321 +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.
- */
-
-var App = require('app');
-var db = require('utils/db');
-
-/**
- * By Step 6, we have the following information stored in App.db and set on this
- * controller by the router:
- *
- *   hosts: App.db.hosts (list of all hosts the user selected in Step 3)
- *   selectedServiceNames: App.db.selectedServiceNames (the services that the user selected in Step 4)
- *   masterComponentHosts: App.db.masterComponentHosts (master-components-to-hosts mapping the user selected in Step 5)
- *
- * Step 6 will set the following information in App.db:
- *   hostSlaveComponents: App.db.hostSlaveComponents (hosts-to-slave-components mapping the user selected in Steo 6)
- *   slaveComponentHosts: App.db.slaveComponentHosts (slave-components-to-hosts mapping the user selected in Step 6)
- *
- */
-App.InstallerStep6Controller = Em.Controller.extend({
-
-
-  hosts: [],
-  // TODO: hook up with user host selection
-  rawHosts: [],
-  selectedServiceNames: [],
-  showHbase: false,
-  showTaskTracker: false,
-
-  hasMasterComponents: function (hostname) {
-    var hasMaster = false;
-    var masterComponentHosts = db.getMasterComponentHosts();
-    return masterComponentHosts.someProperty('hostName', hostname);
-  },
-
-  isAllDataNodes: function () {
-    return this.get('hosts').everyProperty('isDataNode', true);
-  }.property('hosts.@each.isDataNode'),
-
-  isAllTaskTrackers: function () {
-    return this.get('hosts').everyProperty('isTaskTracker', true);
-  }.property('hosts.@each.isTaskTracker'),
-
-  isAllRegionServers: function () {
-    return this.get('hosts').everyProperty('isRegionServer', true);
-  }.property('hosts.@each.isRegionServer'),
-
-  isAllClients: function () {
-    return this.get('hosts').everyProperty('isClient', true);
-  }.property('hosts.@each.isClient'),
-
-  isNoDataNodes: function () {
-    return this.get('hosts').everyProperty('isDataNode', false);
-  }.property('hosts.@each.isDataNode'),
-
-  isNoTaskTrackers: function () {
-    return this.get('hosts').everyProperty('isTaskTracker', false);
-  }.property('hosts.@each.isTaskTracker'),
-
-  isNoRegionServers: function () {
-    return this.get('hosts').everyProperty('isRegionServer', false);
-  }.property('hosts.@each.isRegionServer'),
-
-  isNoClients: function () {
-    return this.get('hosts').everyProperty('isClient', false);
-  }.property('hosts.@each.isClient'),
-
-  isHbaseSelected: function () {
-    var services = db.getSelectedServiceNames();
-    return this.get('selectedServiceNames').contains('HBASE');
-  },
-
-  isMrSelected: function () {
-    return this.get('selectedServiceNames').contains('MAPREDUCE');
-  }.property('selectedServiceNames'),
-
-  clearError: function () {
-    if (this.get('isNoDataNodes') === false && (this.get('isNoTaskTrackers') === false || this.get('isMrSelected') ===
-      false) && (this.get('isNoRegionServers') === false || this.isHbaseSelected() === false) && this.get('isNoClients')
-      === false) {
-      this.set('errorMessage', '');
-    }
-  }.observes('isNoDataNodes', 'isNoTaskTrackers', 'isNoRegionServers', 'isNoClients'),
-
-  selectAllDataNodes: function () {
-    this.get('hosts').setEach('isDataNode', true);
-  },
-
-  selectAllTaskTrackers: function () {
-    this.get('hosts').setEach('isTaskTracker', true);
-  },
-
-  selectAllRegionServers: function () {
-    this.get('hosts').setEach('isRegionServer', true);
-  },
-
-  selectAllClients: function () {
-    this.get('hosts').setEach('isClient', true);
-  },
-
-  deselectAllDataNodes: function () {
-    this.get('hosts').setEach('isDataNode', false);
-  },
-
-  deselectAllTaskTrackers: function () {
-    this.get('hosts').setEach('isTaskTracker', false);
-  },
-
-  deselectAllRegionServers: function () {
-    this.get('hosts').setEach('isRegionServer', false);
-  },
-
-  deselectAllClients: function () {
-    this.get('hosts').setEach('isClient', false);
-  },
-
-  clearStep: function () {
-    this.set('hosts', []);
-    this.set('selectedServiceNames', []);
-    this.clearError();
-  },
-
-  loadStep: function () {
-    console.log("TRACE: Loading step6: Assign Slaves");
-    this.clearStep();
-    this.set('selectedServiceNames', db.getSelectedServiceNames());
-    this.set('showHbase', this.isHbaseSelected());
-    this.set('showTaskTracker', this.get('isMrSelected'));
-    this.setSlaveHost(this.getSlaveHosts());
-  },
-
-  getHostNames: function () {
-    var hostInfo = db.getHosts();
-    var hostNames = [];
-    for (var index in hostInfo) {
-      if (hostInfo[index].bootStatus === 'success')
-        hostNames.push(hostInfo[index].name);
-    }
-    return hostNames;
-  },
-
-  getSlaveHosts: function () {
-    var hostObjs = new Ember.Set();
-    var allHosts = this.getHostNames();
-    var slaveHosts = App.db.getSlaveComponentHosts();
-    if (slaveHosts === undefined || slaveHosts === null) {
-      allHosts.forEach(function (_hostname) {
-        var hostObj = Ember.Object.create({
-          hostname: _hostname,
-          isMaster: this.hasMasterComponents(_hostname),
-          isDataNode: !this.hasMasterComponents(_hostname),
-          isTaskTracker: !this.hasMasterComponents(_hostname),
-          isRegionServer: !this.hasMasterComponents(_hostname),
-          isClient: false
-        });
-        hostObjs.add(hostObj);
-      }, this);
-      if (hostObjs.someProperty('isDataNode', true)) {
-        hostObjs.findProperty('isDataNode', true).set('isClient', true);
-      }
-
-    } else {
-      allHosts.forEach(function (_hostName) {
-        hostObjs.add(Ember.Object.create({
-          hostname: _hostName,
-          isMaster: false,
-          isDataNode: false,
-          isTaskTracker: false,
-          isRegionServer: false,
-          isClient: false
-        }));
-      }, this);
-      var datanodes = slaveHosts.findProperty('componentName', 'DATANODE');
-      datanodes.hosts.forEach(function (_datanode) {
-        var datanode = hostObjs.findProperty('hostname', _datanode.hostname);
-        if (datanode) {
-          datanode.set('isDataNode', true);
-        }
-      }, this);
-      if (this.get('isMrSelected')) {
-        var taskTrackers = slaveHosts.findProperty('componentName', 'TASKTRACKER');
-        taskTrackers.hosts.forEach(function (_taskTracker) {
-          var taskTracker = hostObjs.findProperty('hostname', _taskTracker.hostname);
-          if (taskTracker) {
-            taskTracker.set('isTaskTracker', true);
-          }
-        }, this);
-      }
-      if (this.isHbaseSelected()) {
-        var regionServers = slaveHosts.findProperty('componentName', 'HBASE_REGIONSERVER');
-        regionServers.hosts.forEach(function (_regionServer) {
-          var regionServer = hostObjs.findProperty('hostname', _regionServer.hostname);
-          if (regionServer) {
-            regionServer.set('isRegionServer', true);
-          }
-        }, this);
-      }
-      var clients = slaveHosts.findProperty('componentName', 'CLIENT');
-      clients.hosts.forEach(function (_client) {
-        var client = hostObjs.findProperty('hostname', _client.hostname);
-        if (client) {
-          client.set('isClient', true);
-        }
-      }, this);
-      allHosts.forEach(function (_hostname) {
-        var host = hostObjs.findProperty('hostname', _hostname);
-        if (host) {
-          host.set('isMaster', this.hasMasterComponents(_hostname));
-        }
-      }, this);
-
-    }
-    return hostObjs;
-  },
-
-  getMasterComponentsforHost: function (hostname) {
-    if (App.db.getHostToMasterComponent().someProperty('hostname', hostname)) {
-      return App.db.getHostToMasterComponent().findProperty('hostname', hostname).components;
-    } else {
-      return false;
-    }
-  },
-
-  setSlaveHost: function (hostObj) {
-    hostObj.forEach(function (_hostObj) {
-      this.get('hosts').pushObject(_hostObj);
-    }, this);
-  },
-
-  validate: function () {
-    return !(this.get('isNoDataNodes') || this.get('isNoClients') || (this.get('isMrSelected') &&
-      this.get('isNoTaskTrackers')) || (this.isHbaseSelected() && this.get('isNoRegionServers')));
-  },
-
-  submit: function () {
-    if (!this.validate()) {
-      this.set('errorMessage', Ember.I18n.t('installer.step6.error.mustSelectOne'));
-      return;
-    }
-    App.db.setHostSlaveComponents(this.get('host'));
-
-    var dataNodeHosts = [];
-    var taskTrackerHosts = [];
-    var regionServerHosts = [];
-    var clientHosts = [];
-
-    this.get('hosts').forEach(function (host) {
-      if (host.get('isDataNode')) {
-        dataNodeHosts.pushObject({
-          hostname: host.hostname,
-          group: 'Default'
-        });
-      }
-      if (this.get('isMrSelected') && host.get('isTaskTracker')) {
-        taskTrackerHosts.push({
-          hostname: host.hostname,
-          group: 'Default'
-        });
-      }
-      if (this.isHbaseSelected() && host.get('isRegionServer')) {
-        regionServerHosts.pushObject({
-          hostname: host.hostname,
-          group: 'Default'
-        });
-      }
-      if (host.get('isClient')) {
-        clientHosts.pushObject({
-          hostname: host.hostname,
-          group: 'Default'
-        });
-      }
-    }, this);
-
-    var slaveComponentHosts = [];
-    slaveComponentHosts.pushObject({
-      componentName: 'DATANODE',
-      displayName: 'DataNode',
-      hosts: dataNodeHosts
-    });
-    if (this.get('isMrSelected')) {
-      slaveComponentHosts.pushObject({
-        componentName: 'TASKTRACKER',
-        displayName: 'TaskTracker',
-        hosts: taskTrackerHosts
-      });
-    }
-    if (this.isHbaseSelected()) {
-      slaveComponentHosts.pushObject({
-        componentName: 'HBASE_REGIONSERVER',
-        displayName: 'RegionServer',
-        hosts: regionServerHosts
-      });
-    }
-    slaveComponentHosts.pushObject({
-      componentName: 'CLIENT',
-      displayName: 'client',
-      hosts: clientHosts
-    });
-
-    App.db.setSlaveComponentHosts(slaveComponentHosts);
-    App.router.send('next');
-
-  }
-
-})
-;

+ 11 - 34
ambari-web/app/controllers/login_controller.js

@@ -20,47 +20,24 @@ var App = require('app');
 
 
 App.LoginController = Em.Object.extend({
 App.LoginController = Em.Object.extend({
 
 
-  name:'loginController',
-  loginName:'',
-  password:'',
-  errorMessage:'',
+  name: 'loginController',
+  loginName: '',
+  password: '',
+  errorMessage: '',
 
 
   submit: function (e) {
   submit: function (e) {
-    console.log('Login: ' + this.get('loginName') + ' Password: ' + this.get('password'));
+    // console.log('Login: ' + this.get('loginName') + ' Password: ' + this.get('password'));
 
 
     this.set('errorMessage', '');
     this.set('errorMessage', '');
 
 
-    var user = this.validateCredentials();
-   
-    if (user) {
-      App.get('router').login(this.get('loginName'), user);
-    } else {
-      console.log('Failed to login as: ' + this.get('loginName'));
-      this.set('errorMessage', Em.I18n.t('login.error'));
-    }
-  },
+    var self = this;
 
 
-  /**
-   *
-   * @return {number} user by credentials || {undefined}
-   */
-  validateCredentials: function () {
-    //TODO: REST api that validates the login
-    var thisController = this;
-    var auth = App.get('router').authenticated();
-    console.log(auth);
-//    if (auth) {
-      var user = App.store.filter(App.User, function (data) {
-        return data.get('user_name') == thisController.get('loginName') && data.get('password') == thisController.get('password');
-      });
-
-      var clientId = user.content[0];
-      if (user.content[0] !== undefined) {
-        return App.store.findByClientId(App.User, clientId);
-      } else {
-        return undefined;
+    var user = App.get('router').mockLogin(function (isAuthenticated) {
+      if (!isAuthenticated) {
+        console.log('Failed to login as: ' + self.get('loginName'));
+        self.set('errorMessage', Em.I18n.t('login.error'));
       }
       }
-//    }
+    });
   }
   }
 
 
 });
 });

+ 89 - 13
ambari-web/app/controllers/main/host/add_controller.js

@@ -35,14 +35,15 @@ App.AddHostController = Em.Controller.extend({
    * config??? - to be described later
    * config??? - to be described later
    */
    */
   content: Em.Object.create({
   content: Em.Object.create({
-    cluster: {},
-    hosts: {},
-    services: {},
-    hostsInfo: {},
-    slaveComponentHosts: {},
-    hostSlaveComponents: {},
-    masterComponentHosts: {},
-    serviceConfigProperties: {}
+    cluster: null,
+    hosts: null,
+    services: null,
+    hostsInfo: null,
+    slaveComponentHosts: null,
+    hostSlaveComponents: null,
+    masterComponentHosts: null,
+    hostToMasterComponent : null,
+    serviceConfigProperties: null
   }),
   }),
 
 
   /**
   /**
@@ -193,10 +194,11 @@ App.AddHostController = Em.Controller.extend({
    * Load clusterInfo(step1) to model
    * Load clusterInfo(step1) to model
    */
    */
   loadClusterInfo: function(){
   loadClusterInfo: function(){
+    var cStatus = App.db.getClusterStatus() || {status: "", isCompleted: false};
     var cluster = {
     var cluster = {
-      name: App.db.getClusterName(),
-      status: App.db.getClusterStatus().status,
-      isCompleted: App.db.getClusterStatus().isCompleted
+      name: App.db.getClusterName() || "",
+      status: cStatus.status,
+      isCompleted: cStatus.isCompleted
     };
     };
     this.set('content.cluster', cluster);
     this.set('content.cluster', cluster);
     console.log("AddHostController:loadClusterInfo: loaded data ", cluster);
     console.log("AddHostController:loadClusterInfo: loaded data ", cluster);
@@ -444,6 +446,19 @@ App.AddHostController = Em.Controller.extend({
     console.log("AddHostController.saveComponentHosts: saved hosts ", masterComponentHosts);
     console.log("AddHostController.saveComponentHosts: saved hosts ", masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
+
+    var hosts = masterComponentHosts.mapProperty('hostName').uniq();
+    var hostsMasterServicesMapping = [];
+    hosts.forEach(function (_host) {
+      var componentsOnHost = masterComponentHosts.filterProperty('hostName', _host).mapProperty('component');
+      hostsMasterServicesMapping.push({
+        hostname: _host,
+        components: componentsOnHost
+      });
+    }, this);
+    console.log("AddHostController.setHostToMasterComponent: saved hosts ", hostsMasterServicesMapping);
+    App.db.setHostToMasterComponent(hostsMasterServicesMapping);
+    this.set('content.hostToMasterComponent', hostsMasterServicesMapping);
   },
   },
 
 
   /**
   /**
@@ -453,6 +468,10 @@ App.AddHostController = Em.Controller.extend({
     var masterComponentHosts = App.db.getMasterComponentHosts();
     var masterComponentHosts = App.db.getMasterComponentHosts();
     this.set("content.masterComponentHosts", masterComponentHosts);
     this.set("content.masterComponentHosts", masterComponentHosts);
     console.log("AddHostController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
     console.log("AddHostController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
+
+    var hostsMasterServicesMapping = App.db.getHostToMasterComponent();
+    this.set("content.hostToMasterComponent", hostsMasterServicesMapping);
+    console.log("AddHostController.loadHostToMasterComponent: loaded hosts ", hostsMasterServicesMapping);
   },
   },
 
 
   /**
   /**
@@ -471,6 +490,7 @@ App.AddHostController = Em.Controller.extend({
     var dataNodeHosts = [];
     var dataNodeHosts = [];
     var taskTrackerHosts = [];
     var taskTrackerHosts = [];
     var regionServerHosts = [];
     var regionServerHosts = [];
+    var clientHosts = [];
 
 
     hosts.forEach(function (host) {
     hosts.forEach(function (host) {
       if (host.get('isDataNode')) {
       if (host.get('isDataNode')) {
@@ -491,6 +511,12 @@ App.AddHostController = Em.Controller.extend({
           group: 'Default'
           group: 'Default'
         });
         });
       }
       }
+      if (host.get('isClient')) {
+        clientHosts.pushObject({
+          hostname: host.hostname,
+          group: 'Default'
+        });
+      }
     }, this);
     }, this);
 
 
     var slaveComponentHosts = [];
     var slaveComponentHosts = [];
@@ -513,6 +539,11 @@ App.AddHostController = Em.Controller.extend({
         hosts: regionServerHosts
         hosts: regionServerHosts
       });
       });
     }
     }
+    slaveComponentHosts.pushObject({
+      componentName: 'CLIENT',
+      displayName: 'client',
+      hosts: clientHosts
+    });
 
 
     App.db.setSlaveComponentHosts(slaveComponentHosts);
     App.db.setSlaveComponentHosts(slaveComponentHosts);
     this.set('content.slaveComponentHosts', slaveComponentHosts);
     this.set('content.slaveComponentHosts', slaveComponentHosts);
@@ -532,7 +563,7 @@ App.AddHostController = Em.Controller.extend({
   },
   },
 
 
   /**
   /**
-   * TODO:
+   * Save config properties
    * @param stepController Step7WizardController
    * @param stepController Step7WizardController
    */
    */
   saveServiceConfigProperties: function (stepController) {
   saveServiceConfigProperties: function (stepController) {
@@ -561,6 +592,48 @@ App.AddHostController = Em.Controller.extend({
     console.log("AddHostController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
     console.log("AddHostController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
   },
   },
 
 
+  /**
+   * Load information about hosts with clients components
+   */
+  loadClients: function(){
+    var clients = App.db.getClientsForSelectedServices();
+    this.set('content.clients', clients);
+    console.log("AddHostController.loadClients: loaded list ", clients);
+  },
+
+  /**
+   * Generate clients list for selected services and save it to model
+   * @param stepController step4WizardController
+   */
+  saveClients: function(stepController){
+    var clients = [];
+    var serviceComponents = require('data/service_components');
+
+    stepController.get('content').filterProperty('isSelected',true).forEach(function (_service) {
+      var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
+      if (client) {
+        clients.pushObject({
+          component_name: client.component_name,
+          display_name: client.display_name
+        });
+      }
+    }, this);
+
+    App.db.setClientsForSelectedServices(clients);
+    this.set('content.clients', clients);
+    console.log("AddHostController.saveClients: saved list ", clients);
+  },
+
+  /**
+   * Load HostToMasterComponent array
+   */
+  loadHostToMasterComponent: function(){
+    var list = App.db.getHostToMasterComponent();
+    this.set('content.hostToMasterComponent', list);
+    console.log("AddHostController.loadHostToMasterComponent: loaded list ", list);
+  },
+
+
   /**
   /**
    * Call specified function only once
    * Call specified function only once
    */
    */
@@ -581,12 +654,14 @@ App.AddHostController = Em.Controller.extend({
           //need to call it every time since we preload data in setInfoForStep9
           //need to call it every time since we preload data in setInfoForStep9
         this.loadClusterInfo();
         this.loadClusterInfo();
       case '7':
       case '7':
-        this.callLoadFuncOnce('loadClusterInfo');
+        this.loadClusterInfo();
       case '6':
       case '6':
         this.callLoadFuncOnce('loadServiceConfigProperties');
         this.callLoadFuncOnce('loadServiceConfigProperties');
       case '5':
       case '5':
         this.callLoadFuncOnce('loadMasterComponentHosts');
         this.callLoadFuncOnce('loadMasterComponentHosts');
         this.callLoadFuncOnce('loadSlaveComponentHosts');
         this.callLoadFuncOnce('loadSlaveComponentHosts');
+        this.callLoadFuncOnce('loadClients');
+        this.callLoadFuncOnce('loadHostToMasterComponent');
       case '4':
       case '4':
         this.callLoadFuncOnce('loadConfirmedHosts');
         this.callLoadFuncOnce('loadConfirmedHosts');
       case '3':
       case '3':
@@ -605,6 +680,7 @@ App.AddHostController = Em.Controller.extend({
    */
    */
   clearAllSteps: function () {
   clearAllSteps: function () {
     this.clearHosts();
     this.clearHosts();
+    //todo it)
   }
   }
 
 
 });
 });

+ 67 - 1
ambari-web/app/controllers/main/host/details.js

@@ -27,11 +27,40 @@ App.MainHostDetailsController = Em.Controller.extend({
   isStopping: function(){
   isStopping: function(){
     return !this.get('isStarting');
     return !this.get('isStarting');
   }.property('isStarting'),
   }.property('isStarting'),
+  intervalId: false,
+  checkOperationsInterval: 5000,
+  init: function(){
+    this._super();
+    this.startCheckOperationsLifeTime();
+  },
 
 
   setBack: function(isFromHosts){
   setBack: function(isFromHosts){
     this.set('isFromHosts', isFromHosts);
     this.set('isFromHosts', isFromHosts);
   },
   },
 
 
+  startCheckOperationsLifeTime: function() {
+    this.intervalId = setInterval(this.checkOperationsLifeTime, this.get('checkOperationsInterval'));
+  },
+  stopCheckOperationsLifeTime:function () {
+    if(this.intervalId) {
+      clearInterval(this.intervalId);
+    }
+    this.intervalId = false;
+  },
+
+  checkOperationsLifeTime: function(){
+    var self = App.router.get('mainHostDetailsController');
+    var backgroundOperations = self.get('backgroundOperations');
+    var time = new Date().getTime();
+    if(backgroundOperations.length){
+      backgroundOperations.forEach(function(operation){
+        if (time - operation.time >= 60*1000){
+          backgroundOperations.removeObject(operation);
+        }
+      })
+    }
+  },
+
   hostOperations: function(){
   hostOperations: function(){
     var hostName = this.get('content.hostName');
     var hostName = this.get('content.hostName');
     return this.get('backgroundOperations').filterProperty('hostName', hostName);
     return this.get('backgroundOperations').filterProperty('hostName', hostName);
@@ -72,12 +101,14 @@ App.MainHostDetailsController = Em.Controller.extend({
           "hostName": self.get('content.hostName'),
           "hostName": self.get('content.hostName'),
           "role":component.get('componentName'),
           "role":component.get('componentName'),
           "command": "START",
           "command": "START",
+          "time": new Date().getTime(),
           "details": [
           "details": [
             {"startTime":"4 min ago", "name":"Some intermediate operation"},
             {"startTime":"4 min ago", "name":"Some intermediate operation"},
             {"startTime":"5 min ago", "name":"Component started"}
             {"startTime":"5 min ago", "name":"Component started"}
           ],
           ],
           "logs":{"exitcode":"404", "stdout":27, "stderror":501}
           "logs":{"exitcode":"404", "stdout":27, "stderror":501}
         });
         });
+        self.showBackgroundOperationsPopup();
         var stopped = self.get('content.components').filterProperty('workStatus', false);
         var stopped = self.get('content.components').filterProperty('workStatus', false);
         if (stopped.length == 0)
         if (stopped.length == 0)
           self.set('isStarting', true);
           self.set('isStarting', true);
@@ -103,12 +134,14 @@ App.MainHostDetailsController = Em.Controller.extend({
           "hostName": self.get('content.hostName'),
           "hostName": self.get('content.hostName'),
           "role": component.get('componentName'),
           "role": component.get('componentName'),
           "command": "STOP",
           "command": "STOP",
+          "time": new Date().getTime(),
           "details": [
           "details": [
             {"startTime":"4 min ago", "name":"Some intermediate operation"},
             {"startTime":"4 min ago", "name":"Some intermediate operation"},
             {"startTime":"5 min ago", "name":"Component stopped"}
             {"startTime":"5 min ago", "name":"Component stopped"}
           ],
           ],
           "logs":{"exitcode":"404", "stdout":15, "stderror":501}
           "logs":{"exitcode":"404", "stdout":15, "stderror":501}
         });
         });
+        self.showBackgroundOperationsPopup();
         var started = self.get('content.components').filterProperty('workStatus', true);
         var started = self.get('content.components').filterProperty('workStatus', true);
         if (started.length == 0)
         if (started.length == 0)
           self.set('isStarting', false);
           self.set('isStarting', false);
@@ -121,12 +154,28 @@ App.MainHostDetailsController = Em.Controller.extend({
   },
   },
 
 
   decommission: function(event){
   decommission: function(event){
+    var self = this;
     App.ModalPopup.show({
     App.ModalPopup.show({
       header: Em.I18n.t('hosts.host.start.popup.header'),
       header: Em.I18n.t('hosts.host.start.popup.header'),
       body: Em.I18n.t('hosts.host.start.popup.body'),
       body: Em.I18n.t('hosts.host.start.popup.body'),
       primary: 'Yes',
       primary: 'Yes',
       secondary: 'No',
       secondary: 'No',
       onPrimary: function() {
       onPrimary: function() {
+        var component = event.context;
+        component.set('decommissioned', true);
+        var backgroundOperations = self.get('backgroundOperations');
+        backgroundOperations.pushObject({
+          "hostName": self.get('content.hostName'),
+          "role":component.get('componentName'),
+          "command": "DECOMMISSION",
+          "time": new Date().getTime(),
+          "details": [
+            {"startTime":"4 min ago", "name":"Some intermediate operation"},
+            {"startTime":"5 min ago", "name":"Component decommissioned"}
+          ],
+          "logs":{"exitcode":"404", "stdout":27, "stderror":501}
+        });
+        self.showBackgroundOperationsPopup();
         this.hide();
         this.hide();
       },
       },
       onSecondary: function() {
       onSecondary: function() {
@@ -136,12 +185,28 @@ App.MainHostDetailsController = Em.Controller.extend({
   },
   },
 
 
   recommission: function(event){
   recommission: function(event){
+    var self = this;
     App.ModalPopup.show({
     App.ModalPopup.show({
       header: Em.I18n.t('hosts.host.start.popup.header'),
       header: Em.I18n.t('hosts.host.start.popup.header'),
       body: Em.I18n.t('hosts.host.start.popup.body'),
       body: Em.I18n.t('hosts.host.start.popup.body'),
       primary: 'Yes',
       primary: 'Yes',
       secondary: 'No',
       secondary: 'No',
       onPrimary: function() {
       onPrimary: function() {
+        var component = event.context;
+        component.set('decommissioned', false);
+        var backgroundOperations = self.get('backgroundOperations');
+        backgroundOperations.pushObject({
+          "hostName": self.get('content.hostName'),
+          "role":component.get('componentName'),
+          "command": "RECOMMISSION",
+          "time": new Date().getTime(),
+          "details": [
+            {"startTime":"4 min ago", "name":"Some intermediate operation"},
+            {"startTime":"5 min ago", "name":"Component recommissioned"}
+          ],
+          "logs":{"exitcode":"404", "stdout":27, "stderror":501}
+        });
+        self.showBackgroundOperationsPopup();
         this.hide();
         this.hide();
       },
       },
       onSecondary: function() {
       onSecondary: function() {
@@ -193,7 +258,8 @@ App.MainHostDetailsController = Em.Controller.extend({
     components.forEach(function(cInstance){
     components.forEach(function(cInstance){
       var cName = cInstance.get('componentName');
       var cName = cInstance.get('componentName');
       if(slaveComponents.contains(cName)) {
       if(slaveComponents.contains(cName)) {
-        if(cInstance.get('workStatus')){
+        if(cInstance.get('workStatus') &&
+          !cInstance.get('decommissioned')){
           workingComponents.push(cName);
           workingComponents.push(cName);
         }
         }
       } else {
       } else {

+ 2 - 2
ambari-web/app/controllers/installer/step10_controller.js → ambari-web/app/controllers/wizard/step10_controller.js

@@ -18,8 +18,8 @@
 
 
 var App = require('app');
 var App = require('app');
 
 
-App.InstallerStep10Controller = Em.ArrayController.extend({
-  name: 'installerStep10Controller',
+App.WizardStep10Controller = Em.ArrayController.extend({
+  name: 'wizardStep10Controller',
   content: [],
   content: [],
 
 
   clearStep: function() {
   clearStep: function() {

+ 7 - 4
ambari-web/app/controllers/wizard/step5_controller.js

@@ -38,7 +38,7 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
   },
 
 
   loadStep: function () {
   loadStep: function () {
-    console.log("TRACE: Loading step5: Assign Masters");
+    console.log("WizardStep5Controller: Loading step5: Assign Masters");
     this.clearStep();
     this.clearStep();
     this.renderHostInfo();
     this.renderHostInfo();
     this.renderComponents(this.loadComponents());
     this.renderComponents(this.loadComponents());
@@ -80,7 +80,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       this.get("selectedServices").pushObject(Ember.Object.create({service_name: item}));
       this.get("selectedServices").pushObject(Ember.Object.create({service_name: item}));
     }, this);
     }, this);
 
 
-    var masterHosts = this.get('content.masterHosts');
+    var masterHosts = this.get('content.masterComponentHosts');
 
 
     var components = new Ember.Set();
     var components = new Ember.Set();
     if (!masterHosts) {
     if (!masterHosts) {
@@ -421,8 +421,11 @@ App.WizardStep5Controller = Em.Controller.extend({
 
 
   lastZooKeeper: function () {
   lastZooKeeper: function () {
     var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
     var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper");
-    var lastZooKeeper = currentZooKeepers.get("lastObject");
-    return lastZooKeeper;
+    if(currentZooKeepers){
+      return currentZooKeepers.get("lastObject");
+    }
+
+    return null;
   },
   },
 
 
   addZookeepers: function () {
   addZookeepers: function () {

+ 86 - 18
ambari-web/app/controllers/wizard/step6_controller.js

@@ -35,9 +35,6 @@ var db = require('utils/db');
 App.WizardStep6Controller = Em.Controller.extend({
 App.WizardStep6Controller = Em.Controller.extend({
 
 
   hosts: [],
   hosts: [],
-  // TODO: hook up with user host selection
-  rawHosts: [],
-  masterComponentHosts: require('data/mock/master_component_hosts'),
 
 
   isAllDataNodes: function () {
   isAllDataNodes: function () {
     return this.get('hosts').everyProperty('isDataNode', true);
     return this.get('hosts').everyProperty('isDataNode', true);
@@ -51,6 +48,10 @@ App.WizardStep6Controller = Em.Controller.extend({
     return this.get('hosts').everyProperty('isRegionServer', true);
     return this.get('hosts').everyProperty('isRegionServer', true);
   }.property('hosts.@each.isRegionServer'),
   }.property('hosts.@each.isRegionServer'),
 
 
+  isAllClients: function () {
+    return this.get('hosts').everyProperty('isClient', true);
+  }.property('hosts.@each.isClient'),
+
   isNoDataNodes: function () {
   isNoDataNodes: function () {
     return this.get('hosts').everyProperty('isDataNode', false);
     return this.get('hosts').everyProperty('isDataNode', false);
   }.property('hosts.@each.isDataNode'),
   }.property('hosts.@each.isDataNode'),
@@ -63,6 +64,10 @@ App.WizardStep6Controller = Em.Controller.extend({
     return this.get('hosts').everyProperty('isRegionServer', false);
     return this.get('hosts').everyProperty('isRegionServer', false);
   }.property('hosts.@each.isRegionServer'),
   }.property('hosts.@each.isRegionServer'),
 
 
+  isNoClients: function () {
+    return this.get('hosts').everyProperty('isClient', false);
+  }.property('hosts.@each.isClient'),
+
   /**
   /**
    * Return whether Hbase service was selected or not.
    * Return whether Hbase service was selected or not.
    * Calculate this information on <code>content.services</code> variable
    * Calculate this information on <code>content.services</code> variable
@@ -81,6 +86,15 @@ App.WizardStep6Controller = Em.Controller.extend({
     return this.get('content.services').findProperty('serviceName', 'MAPREDUCE').get('isSelected');
     return this.get('content.services').findProperty('serviceName', 'MAPREDUCE').get('isSelected');
 	}.property('content'),
 	}.property('content'),
 
 
+  clearError: function () {
+    if (this.get('isNoDataNodes') === false &&
+        (this.get('isNoTaskTrackers') === false || this.get('isMrSelected') === false) &&
+        (this.get('isNoRegionServers') === false || this.get('isHbSelected') === false) &&
+        this.get('isNoClients') === false) {
+      this.set('errorMessage', '');
+    }
+  }.observes('isNoDataNodes', 'isNoTaskTrackers', 'isNoRegionServers', 'isNoClients'),
+
   /**
   /**
    * Check whether current host is currently selected as master
    * Check whether current host is currently selected as master
    * @param hostname
    * @param hostname
@@ -102,6 +116,10 @@ App.WizardStep6Controller = Em.Controller.extend({
     this.get('hosts').setEach('isRegionServer', true);
     this.get('hosts').setEach('isRegionServer', true);
   },
   },
 
 
+  selectAllClients: function () {
+    this.get('hosts').setEach('isClient', true);
+  },
+
   deselectAllDataNodes: function () {
   deselectAllDataNodes: function () {
     this.get('hosts').setEach('isDataNode', false);
     this.get('hosts').setEach('isDataNode', false);
   },
   },
@@ -114,12 +132,17 @@ App.WizardStep6Controller = Em.Controller.extend({
     this.get('hosts').setEach('isRegionServer', false);
     this.get('hosts').setEach('isRegionServer', false);
   },
   },
 
 
+  deselectAllClients: function () {
+    this.get('hosts').setEach('isClient', false);
+  },
+
   clearStep: function () {
   clearStep: function () {
     this.set('hosts', []);
     this.set('hosts', []);
+    this.clearError();
   },
   },
 
 
   loadStep: function () {
   loadStep: function () {
-    console.log("TRACE: Loading step6: Assign Slaves");
+    console.log("WizardStep6Controller: Loading step6: Assign Slaves");
     this.clearStep();
     this.clearStep();
     this.renderSlaveHosts();
     this.renderSlaveHosts();
   },
   },
@@ -149,45 +172,72 @@ App.WizardStep6Controller = Em.Controller.extend({
 
 
     allHosts.forEach(function (_hostName) {
     allHosts.forEach(function (_hostName) {
       hostsObj.push(Em.Object.create({
       hostsObj.push(Em.Object.create({
-        hostname: _hostName
+        hostname: _hostName,
+        isMaster: false,
+        isDataNode: false,
+        isTaskTracker: false,
+        isRegionServer: false,
+        isClient: false
       }));
       }));
     });
     });
 
 
     if (!slaveHosts) { // we are at this page for the first time
     if (!slaveHosts) { // we are at this page for the first time
 
 
       hostsObj.forEach(function (host) {
       hostsObj.forEach(function (host) {
+        host.isMaster = this.hasMasterComponents(host.hostname);
         host.isDataNode = host.isTaskTracker
         host.isDataNode = host.isTaskTracker
-            = host.isRegionServer = !this.hasMasterComponents(host.hostname);
+            = host.isRegionServer = !host.isMaster;
       }, this);
       }, this);
 
 
+      if (hostsObj.someProperty('isDataNode', true)) {
+        hostsObj.findProperty('isDataNode', true).set('isClient', true);
+      }
+
     } else {
     } else {
 
 
 			var dataNodes = slaveHosts.findProperty('componentName', 'DATANODE');
 			var dataNodes = slaveHosts.findProperty('componentName', 'DATANODE');
       dataNodes.hosts.forEach(function (_dataNode) {
       dataNodes.hosts.forEach(function (_dataNode) {
         var dataNode = hostsObj.findProperty('hostname', _dataNode.hostname);
         var dataNode = hostsObj.findProperty('hostname', _dataNode.hostname);
         if (dataNode) {
         if (dataNode) {
-          dataNode.isDataNode = true;
+          dataNode.set('isDataNode', true);
         }
         }
       });
       });
 
 
-			var taskTrackers = slaveHosts.findProperty('componentName', 'TASKTRACKER');
-      taskTrackers.hosts.forEach(function (_taskTracker) {
-        var taskTracker = hostsObj.findProperty('hostname', _taskTracker.hostname);
-        if (taskTracker) {
-          taskTracker.isTaskTracker = true;
-        }
-      });
+      if(this.get('isMrSelected')) {
+        var taskTrackers = slaveHosts.findProperty('componentName', 'TASKTRACKER');
+        taskTrackers.hosts.forEach(function (_taskTracker) {
+          var taskTracker = hostsObj.findProperty('hostname', _taskTracker.hostname);
+          if (taskTracker) {
+            taskTracker.set('isTaskTracker', true);
+          }
+        });
+      }
 
 
       if (this.get('isHbSelected')) {
       if (this.get('isHbSelected')) {
 				var regionServers = slaveHosts.findProperty('componentName', 'HBASE_REGIONSERVER');
 				var regionServers = slaveHosts.findProperty('componentName', 'HBASE_REGIONSERVER');
         regionServers.hosts.forEach(function (_regionServer) {
         regionServers.hosts.forEach(function (_regionServer) {
           var regionServer = hostsObj.findProperty('hostname', _regionServer.hostname);
           var regionServer = hostsObj.findProperty('hostname', _regionServer.hostname);
           if (regionServer) {
           if (regionServer) {
-            regionServer.isRegionServer = true;
+            regionServer.set('isRegionServer', true);
           }
           }
         });
         });
       }
       }
 
 
+      var clients = slaveHosts.findProperty('componentName', 'CLIENT');
+      clients.hosts.forEach(function (_client) {
+        var client = hostsObj.findProperty('hostname', _client.hostname);
+        if (client) {
+          client.set('isClient', true);
+        }
+      }, this);
+
+      allHosts.forEach(function (_hostname) {
+        var host = hostsObj.findProperty('hostname', _hostname);
+        if (host) {
+          host.set('isMaster', this.hasMasterComponents(_hostname));
+        }
+      }, this);
+
     }
     }
 
 
     hostsObj.forEach(function(host){
     hostsObj.forEach(function(host){
@@ -195,16 +245,34 @@ App.WizardStep6Controller = Em.Controller.extend({
     }, this);
     }, this);
   },
   },
 
 
+  /**
+   * Return list of master components for specified <code>hostname</code>
+   * @param hostname
+   * @return {*}
+   */
+  getMasterComponentsForHost: function (hostname) {
+    var hostInfo = this.get('content.hostToMasterComponent').findProperty('hostname', hostname);
+    if(hostInfo){
+      return hostInfo.components;
+    }
+
+    return false;
+  },
+
+
   /**
   /**
    * Validate form. Return do we have errors or not
    * Validate form. Return do we have errors or not
    * @return {Boolean}
    * @return {Boolean}
    */
    */
   validate: function () {
   validate: function () {
-    var isOK =  !(this.get('isNoDataNodes') || ( this.get('isMrSelected') && this.get('isNoTaskTrackers')) || ( this.get('isHbSelected') &&this.get('isNoRegionServers')));
-    if(!isOK){
+    var isError =  this.get('isNoDataNodes') || this.get('isNoClients')
+      || ( this.get('isMrSelected') && this.get('isNoTaskTrackers'))
+      || ( this.get('isHbSelected') &&this.get('isNoRegionServers'));
+
+    if(isError){
       this.set('errorMessage', Ember.I18n.t('installer.step6.error.mustSelectOne'));
       this.set('errorMessage', Ember.I18n.t('installer.step6.error.mustSelectOne'));
     }
     }
-    return isOK;
+    return !isError;
   }
   }
 
 
 });
 });

+ 7 - 5
ambari-web/app/models/service.js

@@ -63,13 +63,14 @@ App.Component = DS.Model.extend({
   service:DS.belongsTo('App.Service'),
   service:DS.belongsTo('App.Service'),
   host:DS.belongsTo('App.Host'),
   host:DS.belongsTo('App.Host'),
   workStatus:DS.attr('boolean'),
   workStatus:DS.attr('boolean'),
-  isMaster: function(){
+  isMaster:function () {
     return this.get('type');
     return this.get('type');
   }.property('type'),
   }.property('type'),
-  isSlave: function(){
+  isSlave:function () {
     return !this.get('type');
     return !this.get('type');
   }.property('type'),
   }.property('type'),
   // checkedForHostFilter: true // this is for host page to set checkboxes checked
   // checkedForHostFilter: true // this is for host page to set checkboxes checked
+  decommissioned: DS.attr('boolean')
 });
 });
 
 
 App.Component.FIXTURES = [
 App.Component.FIXTURES = [
@@ -98,7 +99,8 @@ App.Component.FIXTURES = [
     service_id:1,
     service_id:1,
     type:false,
     type:false,
     host_id:2,
     host_id:2,
-    work_status:true
+    work_status:true,
+    decommissioned: true
   },
   },
   {
   {
     id:4,
     id:4,
@@ -139,8 +141,8 @@ App.Component.FIXTURES = [
   {
   {
     id:8,
     id:8,
     component_name:'Oozie',
     component_name:'Oozie',
-    label: 'Oz',
-    type: false,
+    label:'Oz',
+    type:false,
     service_id:5,
     service_id:5,
     host_id:2,
     host_id:2,
     work_status:true
     work_status:true

+ 36 - 30
ambari-web/app/router.js

@@ -34,10 +34,10 @@ App.Router = Em.Router.extend({
   },
   },
 
 
   clearAllSteps: function() {
   clearAllSteps: function() {
-    var totalSteps = 10
+    /*var totalSteps = 10
     for (var step = 1; step <= totalSteps; step++){
     for (var step = 1; step <= totalSteps; step++){
       this.get('installerStep' + step + 'Controller').clearStep();
       this.get('installerStep' + step + 'Controller').clearStep();
-    }
+    }*/
   },
   },
 
 
   /*
   /*
@@ -137,19 +137,6 @@ App.Router = Em.Router.extend({
     return App.db.getUser();
     return App.db.getUser();
   },
   },
 
 
-  login: function (loginName, user) {
-    // TODO: this needs to be hooked up with server authentication
-    console.log("In login function");
-    this.setAuthenticated(true);
-    this.setLoginName(loginName);
-
-//    refactor to get user attributes
-    this.setUser(user);
-
-    this.transitionTo(this.getSection());
-
-  },
-
   resetAuth: function (authenticated) {
   resetAuth: function (authenticated) {
     if (!authenticated){
     if (!authenticated){
       App.db.cleanUp();
       App.db.cleanUp();
@@ -161,10 +148,11 @@ App.Router = Em.Router.extend({
     return authenticated;
     return authenticated;
   },
   },
 
 
-  authenticated: function () {
-    var authenticated = false;
+  login: function (postLogin) {
     var controller = this.get('loginController');
     var controller = this.get('loginController');
-    var hash = ''; //window.btoa(controller.get('loginName') + ":" + controller.get('password'));
+    var hash = window.btoa(controller.get('loginName') + ":" + controller.get('password'));
+    var router = this;
+
     $.ajax({
     $.ajax({
       url : '/api/check',
       url : '/api/check',
       dataType : 'json',
       dataType : 'json',
@@ -172,29 +160,47 @@ App.Router = Em.Router.extend({
       beforeSend: function(xhr) {
       beforeSend: function(xhr) {
         xhr.setRequestHeader("Authorization", "Basic " + hash);
         xhr.setRequestHeader("Authorization", "Basic " + hash);
       },
       },
-      statusCode:{
-        200:function(){
+      statusCode: {
+        200: function() {
           console.log('Authorization status: 200');
           console.log('Authorization status: 200');
-          authenticated = true;
         },
         },
-        401:function(){
+        401: function() {
           console.log('Authorization status: 401');
           console.log('Authorization status: 401');
         },
         },
-        403:function(){
+        403: function(){
           console.log('Authorization status: 403');
           console.log('Authorization status: 403');
         }
         }
       },
       },
-      success: function(data){
-        console.log('Success: ');
+      success: function (data) {
+        console.log('login success');
+        router.setAuthenticated(true);
+        router.setLoginName(loginName);
+        // TODO: set real usr
+        router.setUser(App.User.find(1));
+        router.transitionTo(this.getSection());
+        postLogin(true);
       },
       },
-      error:function (req){
-        console.log("Error: " + req.statusText);
+      error: function (req) {
+        console.log("login error: " + req.statusText);
+        router.setAuthenticated(false);
+        postLogin(false);
       }
       }
     });
     });
-//    this.resetAuth(authenticated);
-    this.setAuthenticated(authenticated);
+  },
 
 
-    return this.getAuthenticated();
+  mockLogin: function (postLogin) {
+    var controller = this.get('loginController');
+
+    if (controller.get('loginName') === 'admin' && controller.get('password') === 'admin') {
+      this.setAuthenticated(true);
+      this.setLoginName('admin');
+      this.setUser(App.User.find(1));
+      this.transitionTo(this.getSection());
+      postLogin(true);
+    } else {
+      this.setAuthenticated(false);
+      postLogin(false);
+    }
   },
   },
 
 
   defaultSection: 'installer',
   defaultSection: 'installer',

+ 25 - 11
ambari-web/app/routes/add_host_routes.js

@@ -131,6 +131,9 @@ module.exports = Em.Route.extend({
       var addHostController = router.get('addHostController');
       var addHostController = router.get('addHostController');
       var wizardStep4Controller = router.get('wizardStep4Controller');
       var wizardStep4Controller = router.get('wizardStep4Controller');
       addHostController.saveServices(wizardStep4Controller);
       addHostController.saveServices(wizardStep4Controller);
+      addHostController.saveClients(wizardStep4Controller);
+      App.db.setMasterComponentHosts(undefined);
+      App.db.setHostToMasterComponent(undefined);
       router.transitionTo('step4');
       router.transitionTo('step4');
     }
     }
   }),
   }),
@@ -150,6 +153,7 @@ module.exports = Em.Route.extend({
       var addHostController = router.get('addHostController');
       var addHostController = router.get('addHostController');
       var wizardStep5Controller = router.get('wizardStep5Controller');
       var wizardStep5Controller = router.get('wizardStep5Controller');
       addHostController.saveMasterComponentHosts(wizardStep5Controller);
       addHostController.saveMasterComponentHosts(wizardStep5Controller);
+      App.db.setSlaveComponentHosts(undefined);
       router.transitionTo('step5');
       router.transitionTo('step5');
     }
     }
   }),
   }),
@@ -170,6 +174,7 @@ module.exports = Em.Route.extend({
 
 
       if (wizardStep6Controller.validate()) {
       if (wizardStep6Controller.validate()) {
         addHostController.saveSlaveComponentHosts(wizardStep6Controller);
         addHostController.saveSlaveComponentHosts(wizardStep6Controller);
+        App.db.setServiceConfigProperties(null);
         router.transitionTo('step6');
         router.transitionTo('step6');
       }
       }
     }
     }
@@ -226,17 +231,26 @@ 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');
-//    },
-//    back: Em.Router.transitionTo('step5'),
-//    next: Em.Router.transitionTo('step7')
-//  }),
-//
+  step9: Em.Route.extend({
+    route: '/step9',
+    connectOutlets: function (router, context) {
+      console.log('in addHost.step9:connectOutlets');
+      var controller = router.get('addHostController');
+      controller.setCurrentStep('9', false);
+      controller.loadAllPriorSteps();
+      controller.connectOutlet('wizardStep10');
+    },
+    back: Em.Router.transitionTo('step8'),
+    complete: function (router, context) {
+      if (true) {   // this function will be moved to installerController where it will validate
+        var addHostController = router.get('addHostController');
+        addHostController.setCurrentStep('1', false);
+        router.transitionTo('hosts');
+      } else {
+        console.log('cluster installation failure');
+      }
+    }
+  }),
 
 
   backToHostsList: function (router, event) {
   backToHostsList: function (router, event) {
     router.transitionTo('hosts');
     router.transitionTo('hosts');

+ 60 - 18
ambari-web/app/routes/installer.js

@@ -59,19 +59,18 @@ module.exports = Em.Route.extend({
 
 
   step1: Em.Route.extend({
   step1: Em.Route.extend({
     route: '/step1',
     route: '/step1',
-    enter: function (router) {
-
-    },
-    connectOutlets: function (router, context) {
+    connectOutlets: function (router) {
       console.log('in installer.step1:connectOutlets');
       console.log('in installer.step1:connectOutlets');
-      router.setNavigationFlow('step1');
+      var controller = router.get('installerController');
       router.setInstallerCurrentStep('1', false);
       router.setInstallerCurrentStep('1', false);
-      router.get('installerController').connectOutlet('installerStep1');
+      controller.loadAllPriorSteps();
+      controller.connectOutlet('wizardStep1', controller.get('content'));
     },
     },
-    next: function (router, context) {
-      // App.db.setAllHostNames(undefined);
-      // App.db.setInstallType(undefined);
-      //App.db.setSoftRepo(undefined);
+
+    next: function (router) {
+      var installerController = router.get('installerController');
+      var wizardStep1Controller = router.get('wizardStep1Controller');
+      installerController.saveClusterInfo(wizardStep1Controller);
       router.transitionTo('step2');
       router.transitionTo('step2');
     }
     }
   }),
   }),
@@ -119,10 +118,18 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       router.setNavigationFlow('step4');
       router.setNavigationFlow('step4');
       router.setInstallerCurrentStep('4', false);
       router.setInstallerCurrentStep('4', false);
-      router.get('installerController').connectOutlet('installerStep4');
+
+      var controller = router.get('installerController');
+      controller.loadAllPriorSteps();
+      controller.connectOutlet('wizardStep4', controller.get('content.services'));
     },
     },
     back: Em.Router.transitionTo('step3'),
     back: Em.Router.transitionTo('step3'),
-    next: function (router, context) {
+    next: function (router) {
+      var controller = router.get('installerController');
+      var wizardStep4Controller = router.get('wizardStep4Controller');
+      controller.saveServices(wizardStep4Controller);
+      controller.saveClients(wizardStep4Controller);
+
       App.db.setMasterComponentHosts(undefined);
       App.db.setMasterComponentHosts(undefined);
       App.db.setHostToMasterComponent(undefined);
       App.db.setHostToMasterComponent(undefined);
       router.transitionTo('step5');
       router.transitionTo('step5');
@@ -134,10 +141,15 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       router.setNavigationFlow('step5');
       router.setNavigationFlow('step5');
       router.setInstallerCurrentStep('5', false);
       router.setInstallerCurrentStep('5', false);
-      router.get('installerController').connectOutlet('installerStep5');
+      var controller = router.get('installerController');
+      controller.loadAllPriorSteps();
+      controller.connectOutlet('wizardStep5', controller.get('content'));
     },
     },
     back: Em.Router.transitionTo('step4'),
     back: Em.Router.transitionTo('step4'),
-    next: function (router, context) {
+    next: function (router) {
+      var controller = router.get('installerController');
+      var wizardStep5Controller = router.get('wizardStep5Controller');
+      controller.saveMasterComponentHosts(wizardStep5Controller);
       App.db.setSlaveComponentHosts(undefined);
       App.db.setSlaveComponentHosts(undefined);
       router.transitionTo('step6');
       router.transitionTo('step6');
     }
     }
@@ -148,12 +160,21 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       router.setNavigationFlow('step6');
       router.setNavigationFlow('step6');
       router.setInstallerCurrentStep('6', false);
       router.setInstallerCurrentStep('6', false);
-      router.get('installerController').connectOutlet('installerStep6');
+
+      var controller = router.get('installerController');
+      controller.loadAllPriorSteps();
+      controller.connectOutlet('wizardStep6', controller.get('content'));
     },
     },
     back: Em.Router.transitionTo('step5'),
     back: Em.Router.transitionTo('step5'),
-    next: function (router, context) {
-      App.db.setServiceConfigProperties(undefined);
-      router.transitionTo('step7');
+    next: function (router) {
+      var controller = router.get('installerController');
+      var wizardStep6Controller = router.get('wizardStep6Controller');
+
+      if (wizardStep6Controller.validate()) {
+        controller.saveSlaveComponentHosts(wizardStep6Controller);
+        App.db.setServiceConfigProperties(null);
+        router.transitionTo('step7');
+      }
     }
     }
   }),
   }),
 
 
@@ -227,6 +248,27 @@ module.exports = Em.Route.extend({
     }
     }
   }),
   }),
 
 
+  step10: Em.Route.extend({
+    route: '/step10',
+    connectOutlets: function (router, context) {
+      console.log('in installer.step10:connectOutlets');
+      var controller = router.get('installerController');
+      router.setInstallerCurrentStep('10', false);
+      controller.loadAllPriorSteps();
+      controller.connectOutlet('wizardStep10');
+    },
+    back: Em.Router.transitionTo('step9'),
+    complete: function (router, context) {
+      if (true) {   // this function will be moved to installerController where it will validate
+        router.setInstallerCurrentStep('1', true);
+        router.setSection('main');
+        router.transitionTo('main');
+      } else {
+        console.log('cluster installation failure');
+      }
+    }
+  }),
+
   gotoStep1: Em.Router.transitionTo('step1'),
   gotoStep1: Em.Router.transitionTo('step1'),
 
 
   gotoStep2: Em.Router.transitionTo('step2'),
   gotoStep2: Em.Router.transitionTo('step2'),

+ 105 - 100
ambari-web/app/styles/application.less

@@ -16,7 +16,7 @@
  * limitations under the License.
  * limitations under the License.
  */
  */
 
 
-.gradient(@color: #FAFAFA, @start: #FFFFFF, @stop: #F2F2F2){
+.gradient(@color: #FAFAFA, @start: #FFFFFF, @stop: #F2F2F2) {
   background: @color;
   background: @color;
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0, @start), color-stop(1, @stop));
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0, @start), color-stop(1, @stop));
   background: -ms-linear-gradient(top, @start, @stop);
   background: -ms-linear-gradient(top, @start, @stop);
@@ -128,7 +128,7 @@ footer {
     font-size: 17px;
     font-size: 17px;
     border-right: 1px solid rgba(0, 0, 0, 0.08);
     border-right: 1px solid rgba(0, 0, 0, 0.08);
   }
   }
-  .operations-count{
+  .operations-count {
     background-color: #006DCC;
     background-color: #006DCC;
   }
   }
   li {
   li {
@@ -244,6 +244,9 @@ h1 {
       color: #FF4B4B;
       color: #FF4B4B;
     }
     }
   }
   }
+  #step6 .pre-scrollable {
+    max-height: 440px;
+  }
   #serviceConfig {
   #serviceConfig {
     .accordion-heading {
     .accordion-heading {
       background-color: #f0f0f0;
       background-color: #f0f0f0;
@@ -576,11 +579,11 @@ a:focus {
 /*end alerts summary*/
 /*end alerts summary*/
 
 
 /*start chart/style graphs*/
 /*start chart/style graphs*/
-.chart-container{
+.chart-container {
   position: relative;
   position: relative;
   margin: 20px 15px 0px 15px;
   margin: 20px 15px 0px 15px;
-  
-  .chart{
+
+  .chart {
     padding-bottom: 0px !important;
     padding-bottom: 0px !important;
     position: relative;
     position: relative;
     height: 160px;
     height: 160px;
@@ -616,6 +619,7 @@ a:focus {
     font-size: small;
     font-size: small;
   }
   }
 }
 }
+
 /*end chart/graph styles*/
 /*end chart/graph styles*/
 
 
 /*****end styles for dashboard page*****/
 /*****end styles for dashboard page*****/
@@ -630,13 +634,10 @@ a:focus {
       list-style: none;
       list-style: none;
       height: 20px;
       height: 20px;
       width: 20px;
       width: 20px;
-      margin-left: 0;
-
-    //      padding-left: 30px;
+      margin-left: 0; //      padding-left: 30px;
     //      padding-right: 30px;
     //      padding-right: 30px;
     //      background-position: 12px 9px;
     //      background-position: 12px 9px;
     //      background-repeat: no-repeat;
     //      background-repeat: no-repeat;
-
     }
     }
     .health-status-LIVE {
     .health-status-LIVE {
       .tab-marker-position;
       .tab-marker-position;
@@ -685,7 +686,7 @@ a:focus {
   }
   }
   .service-content {
   .service-content {
     padding: 5px 0 0 10px;
     padding: 5px 0 0 10px;
-    .service-links{
+    .service-links {
       padding: 5px 0;
       padding: 5px 0;
     }
     }
   }
   }
@@ -719,13 +720,13 @@ a:focus {
   }
   }
 }
 }
 
 
-.summary-metric-graphs{
+.summary-metric-graphs {
   [class*="span"] {
   [class*="span"] {
     float: left;
     float: left;
     margin-left: 10px;
     margin-left: 10px;
   }
   }
-  .chart-container{
-    .chart-x-axis{
+  .chart-container {
+    .chart-x-axis {
       left: 0%;
       left: 0%;
       width: 100%;
       width: 100%;
     }
     }
@@ -810,8 +811,8 @@ a:focus {
       margin-top: 3px;
       margin-top: 3px;
     }
     }
     .dropdown {
     .dropdown {
-       margin-top: 3px;
-     }
+      margin-top: 3px;
+    }
     .dropdown select {
     .dropdown select {
       width: 60px;
       width: 60px;
     }
     }
@@ -831,7 +832,6 @@ a:focus {
     }
     }
     .page-listing {
     .page-listing {
       width: 100px;
       width: 100px;
-
       .table {
       .table {
         th.name {
         th.name {
           width: 300px;
           width: 300px;
@@ -844,87 +844,88 @@ a:focus {
       }
       }
     }
     }
   }
   }
-}
-
-#host-details {
-  .health-status-LIVE {
-    background-image: @status-live-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
-  }
-  .health-status-DEAD {
-    background-image: @status-dead-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
-  }
-  .health-status-DEAD-ORANGE {
-    background-image: @status-dead-orange-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
-  }
-  .health-status-DEAD-YELLOW {
-    background-image: @status-dead-yellow-marker;
-    background-repeat: no-repeat;
-    background-position: 0px 4px;
-  }
-  .back {
-    display: block;
-    width: 105px;
-    margin-bottom: 5px;
-  }
-  .box-header .host-title {
-    margin: 0;
-    padding-left: 17px;
-  }
-  .box-header .button-section {
-    margin-bottom: 5px;
-  }
-  hr {
-    margin-bottom: 0;
-    clear: both;
-  }
-  .content {
-    padding: 10px;
-  }
-  .host-configuration .dl-horizontal dt {
-    width: 90px;
-    line-height: 20px;
-  }
-  .host-configuration .dl-horizontal dd {
-    margin-left: 100px;
-    line-height: 20px;
   }
   }
-  .host-components {
-    padding: 10px;
-    padding-bottom: 0;
-    border: 1px solid #DEDEDE;
-    border-radius: 4px;
-    background: #F5F5F5;
-  }
-  .host-components .btn-group {
-    margin: 0 5px 10px 0;
-  }
-}
-.background-operations {
-  .open-details{
-    clear: left;
-    display: block;
-    float: left;
-    text-decoration: none;
-    width: 16px;
+
+  #host-details {
+    .health-status-LIVE {
+      background-image: @status-live-marker;
+      background-repeat: no-repeat;
+      background-position: 0px 4px;
+    }
+    .health-status-DEAD {
+      background-image: @status-dead-marker;
+      background-repeat: no-repeat;
+      background-position: 0px 4px;
+    }
+    .health-status-DEAD-ORANGE {
+      background-image: @status-dead-orange-marker;
+      background-repeat: no-repeat;
+      background-position: 0px 4px;
+    }
+    .health-status-DEAD-YELLOW {
+      background-image: @status-dead-yellow-marker;
+      background-repeat: no-repeat;
+      background-position: 0px 4px;
+    }
+    .back {
+      display: block;
+      width: 105px;
+      margin-bottom: 5px;
+    }
+    .box-header .host-title {
+      margin: 0;
+      padding-left: 17px;
+    }
+    .box-header .button-section {
+      margin-bottom: 5px;
+    }
+    hr {
+      margin-bottom: 0;
+      clear: both;
+    }
+    .content {
+      padding: 10px;
+    }
+    .host-configuration .dl-horizontal dt {
+      width: 90px;
+      line-height: 20px;
+    }
+    .host-configuration .dl-horizontal dd {
+      margin-left: 100px;
+      line-height: 20px;
+    }
+    .host-components {
+      padding: 10px;
+      padding-bottom: 0;
+      border: 1px solid #DEDEDE;
+      border-radius: 4px;
+      background: #F5F5F5;
+    }
+    .host-components .btn-group {
+      margin: 0 5px 10px 0;
+    }
   }
   }
-  .operation-details {
-    padding-left: 16px;
-    padding-top: 5px;
-    display: none;
+  .background-operations {
+    .open-details {
+      clear: left;
+      display: block;
+      float: left;
+      text-decoration: none;
+      width: 16px;
+    }
+    .operation-details {
+      padding-left: 16px;
+      padding-top: 5px;
+      display: none;
+    }
+    margin-bottom: 10px;
   }
   }
-margin-bottom: 10px;
-}
-.background-operations.is-open {
-  .operation-details {
-    display: block;
+  .background-operations.is-open {
+    .operation-details {
+      display: block;
+    }
   }
   }
-}
+
 /*End Hosts*/
 /*End Hosts*/
 
 
 /*assign masters*/
 /*assign masters*/
@@ -1491,6 +1492,7 @@ ul.inline li {
 .ui-timepicker-rtl dl dd {
 .ui-timepicker-rtl dl dd {
   margin: 0 65px 10px 10px;
   margin: 0 65px 10px 10px;
 }
 }
+
 /* end css for timepicker */
 /* end css for timepicker */
 
 
 #slider {
 #slider {
@@ -1511,20 +1513,20 @@ ul.inline li {
 
 
 /* TIME RANGE WIDGET END */
 /* TIME RANGE WIDGET END */
 
 
-#host-details .host-components .btn-group > .btn{
+#host-details .host-components .btn-group > .btn {
   min-width: 130px;
   min-width: 130px;
 }
 }
 
 
-#host-details > .host-maintenance{
+#host-details > .host-maintenance {
   text-align: right;
   text-align: right;
   margin-top: -20px;
   margin-top: -20px;
 }
 }
 
 
-#host-details > .host-maintenance > div{
+#host-details > .host-maintenance > div {
   text-align: left;
   text-align: left;
 }
 }
 
 
-#host-details > .host-title{
+#host-details > .host-title {
   background-position: 0px center;
   background-position: 0px center;
   padding-left: 17px;
   padding-left: 17px;
 }
 }
@@ -1534,26 +1536,29 @@ ul.inline li {
   border: 2px solid black;
   border: 2px solid black;
   padding: 10px;
   padding: 10px;
 }
 }
+
 .fieldset legend {
 .fieldset legend {
   border-bottom: none;
   border-bottom: none;
   width: auto;
   width: auto;
   font-size: 14px;
   font-size: 14px;
 }
 }
+
 /* fieldset end */
 /* fieldset end */
 
 
 /* Start Carousel */
 /* Start Carousel */
 .carousel-inner {
 .carousel-inner {
   height: 80px;
   height: 80px;
 }
 }
+
 /* End Carousel*/
 /* End Carousel*/
 
 
 #add-host .back,
 #add-host .back,
-#add-service .back{
+#add-service .back {
   display: block;
   display: block;
   width: 105px;
   width: 105px;
   margin-bottom: 10px;
   margin-bottom: 10px;
 }
 }
 
 
-#step8-content{
+#step8-content {
   max-height: 570px;
   max-height: 570px;
-}
+}

+ 0 - 42
ambari-web/app/templates/installer/step1.hbs

@@ -1,42 +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.
--->
-
-<h2>{{t installer.step1.body.header}}</h2>
-<p class="alert alert-info">
-  {{t installer.step1.body}}
-</p>
-<div {{bindAttr class="view.onError:error :control-group"}}>
-  <label class="control-label" for="cluster-name">{{t installer.step1.clusterName}}
-    <a href="javascript:void(null)"
-       rel="popover"
-      {{translateAttr title="installer.step1.clusterName.tooltip.title"
-       data-content="installer.step1.clusterName.tooltip.content"}}>Learn more</a>
-  </label>
-
-  <div class="controls">
-    {{view Ember.TextField id="cluster-name" valueBinding="clusterName" placeholder="cluster name" target="controller"}}
-    <p class="help-inline">{{clusterNameError}}</p>
-  </div>
-</div>
-
-<div class="btn-area">
-  <a class="btn btn-success pull-right" {{bindAttr disabled= "invalidClusterName"}} {{action "submit" target="controller"}}>Next &rarr;</a>
-</div>
-
-
-

+ 0 - 56
ambari-web/app/templates/installer/step4.hbs

@@ -1,56 +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.
--->
-
-
-<div id="step4">
-<h2>{{t installer.step4.header}}</h2>
-<div class="alert alert-info">
-  {{t installer.step4.body}}
-</div>
-  <table class="table table-striped">
-    <thead>
-    <tr>
-      <th class="span3">Service
-        <span style="margin-left:10px">
-          <a href="#" {{action selectAll target="controller"}} {{bindAttr class="isAll:selected:deselected"}}>all</a>
-          |
-          <a href="#" {{action selectMinimum target="controller"}} {{bindAttr class="isMinimum:selected:deselected"}}>minimum</a>
-        </span>
-      </th>
-      <th>Description</th>
-    </tr>
-    </thead>
-    <tbody>
-    {{#each controller}}
-    {{#unless isHidden}}
-    <tr {{bindAttr class="isSelected:success:"}}>
-      <td><label
-        class="checkbox">{{view Ember.Checkbox disabledBinding="isDisabled" checkedBinding="isSelected"}}{{displayName}}</label>
-      </td>
-      <td>{{description}}</td>
-    </tr>
-    {{/unless}}
-    {{/each}}
-    </tbody>
-  </table>
-
-  <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>
-  </div>
-</div>

+ 0 - 76
ambari-web/app/templates/installer/step5.hbs

@@ -1,76 +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.
--->
-
-<h2>{{t installer.step5.header}}</h2>
-<div class="alert alert-info">
-  {{t installer.step5.body}}
-</div>
-<div class="assign-masters">
-  <div class="select-hosts">
-    <form class="form-horizontal">
-      <!-- View for array controller -->
-      {{#each selectedServicesMasters}}
-      <div class="control-group">
-        <label class="control-label">{{component_name}}:</label>
-
-        <div class="controls">
-          {{view App.SelectHostView
-            contentBinding="availableHosts"
-            optionValuePath="content.host_name"
-            optionLabelPath="content.host_info"
-            selectedHostBinding="selectedHost"
-            serviceNameBinding="component_name"
-            zIdBinding="zId"
-          }}
-          {{#if showAddControl}}
-          {{view App.AddControlView
-            componentNameBinding="component_name"
-          }}
-          {{/if}}
-          {{#if showRemoveControl}}
-          {{view App.RemoveControlView
-            zIdBinding="zId"
-          }}
-          {{/if}}
-        </div>
-      </div>
-      {{/each}}
-    </form>
-  </div>
-
-  <div class="host-assignments">
-    {{#each masterHostMapping}}
-    <div class="mapping-box round-corners well">
-      <div class="hostString"><span><strong>{{host_name}}</strong></span><span>{{hostInfo}}</span></div>
-      {{#each masterServices}}
-      <span class="assignedService round-corners">{{component_name}}</span>
-      {{/each}}
-    </div>
-    {{/each}}
-
-    {{#if remainingHosts}}
-    <div class="remaining-hosts round-corners well">
-      <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
-    {{/if}}
-  </div>
-  <div style="clear: both;"></div>
-</div>
-<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>
-</div>

+ 0 - 81
ambari-web/app/templates/installer/step6.hbs

@@ -1,81 +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.
--->
-
-<div id="step6">
-  <h2>{{t installer.step6.header}}</h2>
-
-  <div class="alert alert-info">{{{view.label}}}</div>
-  {{#if errorMessage}}
-  <div class="alert alert-error">{{errorMessage}}</div>
-  {{/if}}
-
-  <div class="pre-scrollable" style="max-height: 440px;">
-    <table class="table table-striped">
-      <thead>
-      <tr>
-        <th>Host</th>
-        <th>
-          <a href="#" {{bindAttr class="isAllDataNodes:selected:deselected"}} {{action selectAllDataNodes target="controller"}}>all</a>
-          |
-          <a href="#" {{bindAttr class="isNoDataNodes:selected:deselected"}} {{action deselectAllDataNodes target="controller"}}>none</a>
-        </th>
-        {{#if controller.isMrSelected}}
-        <th>
-          <a href="#" {{bindAttr class="isAllTaskTrackers:selected:deselected"}} {{action selectAllTaskTrackers target="controller"}}>all</a>
-          |
-          <a href="#" {{bindAttr class="isNoTaskTrackers:selected:deselected"}} {{action deselectAllTaskTrackers target="controller"}}>none</a>
-        </th>
-        {{/if}}
-        {{#if showHbase}}
-        <th>
-          <a href="#" {{bindAttr class="isAllRegionServers:selected:deselected"}} {{action selectAllRegionServers target="controller"}}>all</a>
-          |
-          <a href="#" {{bindAttr class="isNoRegionServers:selected:deselected"}} {{action deselectAllRegionServers target="controller"}}>none</a>
-        </th>
-        {{/if}}
-        <th>
-          <a href="#" {{bindAttr class="isAllClients:selected:deselected"}} {{action selectAllClients target="controller"}}>all</a>
-          |
-          <a href="#" {{bindAttr class="isNoClients:selected:deselected"}} {{action deselectAllClients target="controller"}}>none</a>
-        </th>
-      </tr>
-      </thead>
-      <tbody>
-
-      {{#each hosts}}
-      <tr>
-        {{#view App.InstallerStep6HostView hostBinding = "this" }} {{hostname}} {{#if isMaster}}<i
-              class=icon-asterisks>&#10037</i>{{/if}}{{/view}}
-        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isDataNode"}}DataNode</label></td>
-        {{#if controller.isMrSelected}}
-        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isTaskTracker"}}TaskTracker</label></td>
-        {{/if}}
-        {{#if controller.showHbase}}
-        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isRegionServer"}}RegionServer</label></td>
-        {{/if}}
-        <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isClient"}}Client</label></td>
-      </tr>
-      {{/each}}
-      </tbody>
-    </table>
-  </div>
-  <div class="btn-area">
-    <a class="btn" {{action back}}>&larr; Back</a>
-    <a class="btn btn-success" style="float:right" {{action submit target="controller"}}>Next &rarr;</a>
-  </div>
-</div>

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/hbase.hbs

@@ -18,7 +18,7 @@
 
 
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
-    {{view App.MainDashboardServiceHealthView parentBinding="view"}}
+    {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/hive.hbs

@@ -18,7 +18,7 @@
 
 
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
-    {{view App.MainDashboardServiceHealthView parentBinding="view"}}
+    {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/mapreduce.hbs

@@ -17,7 +17,7 @@
 -->
 -->
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
-    {{view App.MainDashboardServiceHealthView parentBinding="view"}}
+    {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
       <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
       <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/oozie.hbs

@@ -18,7 +18,7 @@
 
 
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
-    {{view App.MainDashboardServiceHealthView parentBinding="view"}}
+    {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/zookeeper.hbs

@@ -18,7 +18,7 @@
 
 
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
-    {{view App.MainDashboardServiceHealthView parentBinding="view"}}
+    {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>

+ 4 - 4
ambari-web/app/templates/main/host.hbs

@@ -21,7 +21,7 @@
       <div class="btn-group">
       <div class="btn-group">
         <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary dropdown-toggle"
         <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary dropdown-toggle"
                                                               data-toggle="dropdown">
                                                               data-toggle="dropdown">
-          Rack
+          Assign Rack
           <span class="caret"></span>
           <span class="caret"></span>
         </button>
         </button>
         <ul class="dropdown-menu">
         <ul class="dropdown-menu">
@@ -35,17 +35,17 @@
           {{/each}}
           {{/each}}
         </ul>
         </ul>
       </div>
       </div>
-      <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary decommission"
+     <!-- <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary decommission"
                                                             data-toggle="modal" {{action "decommissionButtonPopup" target="controller"}}>
                                                             data-toggle="modal" {{action "decommissionButtonPopup" target="controller"}}>
         Decommission
         Decommission
       </button>
       </button>
       <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary"
       <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary"
                                                             data-toggle="modal" {{action "deleteButtonPopup" target="controller"}}>
                                                             data-toggle="modal" {{action "deleteButtonPopup" target="controller"}}>
         Delete
         Delete
-      </button>
+      </button>-->
       <button class="btn btn-inverse add-host-button" {{action addHost}}>
       <button class="btn btn-inverse add-host-button" {{action addHost}}>
         <i class="icon-plus icon-white"></i>
         <i class="icon-plus icon-white"></i>
-        Add New Host
+        Add New Hosts
       </button>
       </button>
     </div>
     </div>
   </div>
   </div>

+ 2 - 2
ambari-web/app/templates/main/host/summary.hbs

@@ -38,12 +38,12 @@
         </button>
         </button>
         <ul class="dropdown-menu">
         <ul class="dropdown-menu">
           {{#if view.isDataNode}}
           {{#if view.isDataNode}}
-            <li>
+            <li {{bindAttr class="view.content.decommissioned:hidden:"}}>
               <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
               <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
                 Decommission
                 Decommission
               </a>
               </a>
             </li>
             </li>
-            <li>
+            <li {{bindAttr class="view.content.decommissioned::hidden"}}>
               <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
               <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
                 Recommission
                 Recommission
               </a>
               </a>

+ 5 - 5
ambari-web/app/templates/main/menu_item.hbs

@@ -22,9 +22,9 @@
       {{view.alertsCount}}
       {{view.alertsCount}}
     </span>
     </span>
   {{/if}}
   {{/if}}
-  {{#if view.hostDetailsOperationsCount}}
-    <span class="label operations-count" {{action "showBackgroundOperationsPopup" target="App.router.mainHostDetailsController"}}>
-      {{view.hostDetailsOperationsCount}}
-    </span>
-  {{/if}}
+  <!--{{#if view.hostDetailsOperationsCount}}-->
+    <!--<span class="label operations-count" {{action "showBackgroundOperationsPopup" target="App.router.mainHostDetailsController"}}>-->
+      <!--{{view.hostDetailsOperationsCount}}-->
+    <!--</span>-->
+  <!--{{/if}}-->
 </a>
 </a>

+ 1 - 1
ambari-web/app/templates/wizard/step1.hbs

@@ -29,7 +29,7 @@
   </label>
   </label>
 
 
   <div class="controls">
   <div class="controls">
-    {{view Ember.TextField id="cluster-name" valueBinding="content.name" placeholder="cluster name" target="controller"}}
+    {{view Ember.TextField id="cluster-name" valueBinding="content.cluster.name" placeholder="cluster name" target="controller"}}
     <p class="help-inline">{{clusterNameError}}</p>
     <p class="help-inline">{{clusterNameError}}</p>
   </div>
   </div>
 </div>
 </div>

+ 0 - 0
ambari-web/app/templates/installer/step10.hbs → ambari-web/app/templates/wizard/step10.hbs


+ 16 - 2
ambari-web/app/templates/wizard/step6.hbs

@@ -19,10 +19,12 @@
 <div id="step6">
 <div id="step6">
   <h2>{{t installer.step6.header}}</h2>
   <h2>{{t installer.step6.header}}</h2>
 
 
-  <div class="alert alert-info">{{t installer.step6.body}}</div>
+  <div class="alert alert-info">{{{view.label}}}</div>
   {{#if errorMessage}}
   {{#if errorMessage}}
   <div class="alert alert-error">{{errorMessage}}</div>
   <div class="alert alert-error">{{errorMessage}}</div>
   {{/if}}
   {{/if}}
+
+  <div class="pre-scrollable">
   <table class="table table-striped">
   <table class="table table-striped">
     <thead>
     <thead>
       <tr>
       <tr>
@@ -52,13 +54,23 @@
             {{action deselectAllRegionServers target="controller"}}>none</a>
             {{action deselectAllRegionServers target="controller"}}>none</a>
         </th>
         </th>
       {{/if}}
       {{/if}}
+        <th>
+          <a href="#" {{bindAttr class="isAllClients:selected:deselected"}} {{action selectAllClients target="controller"}}>all</a>
+          |
+          <a href="#" {{bindAttr class="isNoClients:selected:deselected"}} {{action deselectAllClients target="controller"}}>none</a>
+        </th>
       </tr>
       </tr>
     </thead>
     </thead>
     <tbody>
     <tbody>
 
 
     {{#each hosts}}
     {{#each hosts}}
     <tr>
     <tr>
-      <td>{{hostname}}</td>
+        {{#view App.WizardStep6HostView hostBinding = "this" }}
+          {{hostname}}
+          {{#if isMaster}}
+            <i class=icon-asterisks>&#10037</i>
+          {{/if}}
+        {{/view}}
       <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isDataNode"}}DataNode</label></td>
       <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isDataNode"}}DataNode</label></td>
       {{#if controller.isMrSelected}}
       {{#if controller.isMrSelected}}
       <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isTaskTracker"}}TaskTracker</label></td>
       <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isTaskTracker"}}TaskTracker</label></td>
@@ -66,10 +78,12 @@
       {{#if controller.isHbSelected}}
       {{#if controller.isHbSelected}}
       <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isRegionServer"}}RegionServer</label></td>
       <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isRegionServer"}}RegionServer</label></td>
       {{/if}}
       {{/if}}
+      <td><label class="checkbox">{{view Ember.Checkbox checkedBinding="isClient"}}Client</label></td>
     </tr>
     </tr>
     {{/each}}
     {{/each}}
     </tbody>
     </tbody>
   </table>
   </table>
+  </div>
   <div class="btn-area">
   <div class="btn-area">
     <a class="btn" {{action back href="true"}}>&larr; Back</a>
     <a class="btn" {{action back href="true"}}>&larr; Back</a>
     <a class="btn btn-success pull-right" {{action next}}>Next &rarr;</a>
     <a class="btn btn-success pull-right" {{action next}}>Next &rarr;</a>

+ 78 - 0
ambari-web/app/utils/base64.js

@@ -0,0 +1,78 @@
+/**
+ * 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.
+ */
+
+(function () {
+
+  var
+    object = typeof window != 'undefined' ? window : exports,
+    chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
+    INVALID_CHARACTER_ERR = (function () {
+      // fabricate a suitable error object
+      try {
+        document.createElement('$');
+      }
+      catch (error) {
+        return error;
+      }
+    }());
+
+  // encoder
+  // [https://gist.github.com/999166] by [https://github.com/nignag]
+  object.btoa || (
+    object.btoa = function (input) {
+      for (
+        // initialize result and counter
+        var block, charCode, idx = 0, map = chars, output = '';
+        // if the next input index does not exist:
+        // change the mapping table to "="
+        // check if d has no fractional digits
+        input.charAt(idx | 0) || (map = '=', idx % 1);
+        // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
+        output += map.charAt(63 & block >> 8 - idx % 1 * 8)
+        ) {
+        charCode = input.charCodeAt(idx += 3 / 4);
+        if (charCode > 0xFF) throw INVALID_CHARACTER_ERR;
+        block = block << 8 | charCode;
+      }
+      return output;
+    });
+
+  // decoder
+  // [https://gist.github.com/1020396] by [https://github.com/atk]
+  object.atob || (
+    object.atob = function (input) {
+      input = input.replace(/=+$/, '')
+      if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR;
+      for (
+        // initialize result and counters
+        var bc = 0, bs, buffer, idx = 0, output = '';
+        // get next character
+        buffer = input.charAt(idx++);
+        // character found in table? initialize bit storage and add its ascii value;
+        ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
+          // and if not first of each 4 characters,
+          // convert the first 8 bits to one ascii character
+          bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
+        ) {
+        // try to find character in table (0-63, not found => -1)
+        buffer = chars.indexOf(buffer);
+      }
+      return output;
+    });
+
+}());

+ 1 - 5
ambari-web/app/views.js

@@ -100,13 +100,8 @@ require('views/main/charts/heatmap/heatmap_host_detail');
 require('views/main/apps_view');
 require('views/main/apps_view');
 require('views/main/apps/item_view');
 require('views/main/apps/item_view');
 require('views/installer');
 require('views/installer');
-require('views/installer/step1_view');
 require('views/installer/step2_view');
 require('views/installer/step2_view');
 require('views/installer/step3_view');
 require('views/installer/step3_view');
-require('views/installer/step4_view');
-require('views/installer/step5_view');
-require('views/installer/step6_view');
-require('views/installer/step10_view');
 require('views/wizard/controls_view');
 require('views/wizard/controls_view');
 require('views/wizard/step1_view');
 require('views/wizard/step1_view');
 require('views/wizard/step2_view');
 require('views/wizard/step2_view');
@@ -117,3 +112,4 @@ require('views/wizard/step6_view');
 require('views/wizard/step7_view');
 require('views/wizard/step7_view');
 require('views/wizard/step8_view');
 require('views/wizard/step8_view');
 require('views/wizard/step9_view');
 require('views/wizard/step9_view');
+require('views/wizard/step10_view');

+ 0 - 41
ambari-web/app/views/installer/step1_view.js

@@ -1,41 +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.
- */
-
-
-var App = require('app');
-
-App.InstallerStep1View = Em.View.extend({
-
-  templateName: require('templates/installer/step1'),
-
-  didInsertElement: function () {
-    $("[rel=popover]").popover({'placement': 'right', 'trigger': 'hover'});
-    var controller = this.get('controller');
-    controller.loadStep();
-
-  },
-
-  onError: function () {
-    if (this.get('controller.clusterNameError') !== '') {
-      return true;
-    } else {
-      return false;
-    }
-  }.property('controller.clusterNameError')
-
-});

+ 0 - 31
ambari-web/app/views/installer/step4_view.js

@@ -1,31 +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.
- */
-
-
-var App = require('app');
-
-App.InstallerStep4View = Em.View.extend({
-
-  templateName: require('templates/installer/step4'),
-
-  didInsertElement: function () {
-    var controller = this.get('controller');
-    controller.loadStep();
-  }
-
-});

+ 0 - 74
ambari-web/app/views/installer/step5_view.js

@@ -1,74 +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.
- */
-
-
-var App = require('app');
-
-App.InstallerStep5View = Em.View.extend({
-
-  templateName: require('templates/installer/step5'),
-
-  didInsertElement: function () {
-    var controller = this.get('controller');
-    controller.loadStep();
-    if (controller.lastZooKeeper()) {
-      if (controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").length < controller.get("hosts.length")) {
-        controller.lastZooKeeper().set('showAddControl', true);
-      } else {
-        controller.lastZooKeeper().set('showRemoveControl', false);
-      }
-    }
-  }
-});
-
-App.SelectHostView = Em.Select.extend({
-  content: [],
-  zId: null,
-  selectedHost: null,
-  serviceName: null,
-
-  change: function () {
-    this.get('controller').assignHostToMaster(this.get("serviceName"), this.get("value"), this.get("zId"));
-  },
-
-  didInsertElement: function () {
-    this.set("value", this.get("selectedHost"));
-  }
-});
-
-App.AddControlView = Em.View.extend({
-  componentName: null,
-  tagName: "span",
-  classNames: ["badge", "badge-important"],
-  template: Ember.Handlebars.compile('+'),
-
-  click: function (event) {
-    this.get('controller').addZookeepers();
-  }
-});
-
-App.RemoveControlView = Em.View.extend({
-  zId: null,
-  tagName: "span",
-  classNames: ["badge", "badge-important"],
-  template: Ember.Handlebars.compile('-'),
-
-  click: function (event) {
-    this.get('controller').removeZookeepers(this.get("zId"));
-  }
-});

+ 0 - 80
ambari-web/app/views/installer/step6_view.js

@@ -1,80 +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.
- */
-
-
-var App = require('app');
-
-App.InstallerStep6View = Em.View.extend({
-
-  templateName: require('templates/installer/step6'),
-  label: '',
-
-  didInsertElement: function () {
-    var controller = this.get('controller');
-    this.setLabel();
-    var client = App.db.getClientsForSelectedServices();
-    this.set('client', client);
-    var self = this;
-    $('body').tooltip({
-      selector: '[rel=tooltip]'
-    });
-    controller.loadStep();
-  },
-
-  setLabel: function () {
-    var label = Em.I18n.t('installer.step6.body');
-    var clients = App.db.getClientsForSelectedServices();
-    clients.forEach(function (_client) {
-      if (clients.length === 1) {
-        label = label + ' ' + _client.display_name;
-      } else if (_client !== clients[clients.length - 1]) {           // [clients.length - 1]
-        label = label + ' ' + _client.display_name;
-        if(_client !== clients[clients.length - 2]) {
-          label = label + ',';
-        }
-      } else {
-        label = label + ' and ' + _client.display_name + '.';
-      }
-    }, this);
-    this.set('label', label);
-  }
-});
-
-App.InstallerStep6HostView = Em.View.extend({
-
-  host: null,
-  tagName: 'td',
-  didInsertElement: function (event, context) {
-    var self = this;
-    var components = this.get('controller').getMasterComponentsforHost(this.get('host.hostname')).toString();
-    components = components.replace(/,/g, " /\n");
-    if (components === 'false') {
-      return;
-    } else {
-      this.$().popover({
-        title: 'master components hosted on ' + self.get('host.hostname'),
-        content: components,
-        placement: 'right',
-        trigger: 'hover'
-      });
-    }
-  }
-});
-
-
-

+ 2 - 2
ambari-web/app/views/main/admin/menu.js

@@ -27,7 +27,7 @@ App.MainAdminMenuView = Em.CollectionView.extend({
     {
     {
       route:'authentication',
       route:'authentication',
       label:'Authentication'
       label:'Authentication'
-    },
+    }/*,
     {
     {
       route:'security',
       route:'security',
       label:'Security'
       label:'Security'
@@ -35,7 +35,7 @@ App.MainAdminMenuView = Em.CollectionView.extend({
     {
     {
       route:'audit',
       route:'audit',
       label:'Audit'
       label:'Audit'
-    }
+    }*/
     /*,
     /*,
     {
     {
       route:'advanced',
       route:'advanced',

+ 2 - 2
ambari-web/app/views/main/charts/menu.js

@@ -22,8 +22,8 @@ App.MainChartsMenuView = Em.CollectionView.extend({
   tagName: 'ul',
   tagName: 'ul',
   classNames: ["nav", "nav-tabs"],
   classNames: ["nav", "nav-tabs"],
   content:[
   content:[
-    { label:'Heatmap', routing:'heatmap', active:"active"},
-    { label:'Horizon Chart', routing:'horizon_chart'}
+    /*{ label:'Heatmap', routing:'heatmap', active:"active"},
+    { label:'Horizon Chart', routing:'horizon_chart'}*/
   ],
   ],
 
 
   init: function(){ this._super(); this.activateView(); },
   init: function(){ this._super(); this.activateView(); },

+ 2 - 2
ambari-web/app/views/main/host/menu.js

@@ -22,8 +22,8 @@ App.MainHostMenuView = Em.CollectionView.extend({
   tagName: 'ul',
   tagName: 'ul',
   classNames: ["nav", "nav-tabs"],
   classNames: ["nav", "nav-tabs"],
   content:[
   content:[
-    { label:'Summary', routing:'summary'},
-    { label:'Audit', routing:'audit'}
+ /*   { label:'Summary', routing:'summary'},
+    { label:'Audit', routing:'audit'}*/
   ],
   ],
 
 
   init: function(){ this._super(); this.activateView(); },
   init: function(){ this._super(); this.activateView(); },

+ 7 - 7
ambari-web/app/views/main/menu.js

@@ -69,13 +69,13 @@ App.MainMenuView = Em.CollectionView.extend({
       }
       }
     }.property(),
     }.property(),
 
 
-    hostDetailsOperationsCount:function () {
-      if (this.get('content').routing == 'hosts') {
-        if (App.router.currentState.parentState.name == 'hostDetails') {
-          return App.router.get('mainHostDetailsController.hostOperationsCount');
-        }
-      }
-    }.property('App.router.currentState.parentState.name', 'App.router.mainHostDetailsController.hostOperationsCount'),
+//    hostDetailsOperationsCount:function () {
+//      if (this.get('content').routing == 'hosts') {
+//        if (App.router.currentState.parentState.name == 'hostDetails') {
+//          return App.router.get('mainHostDetailsController.hostOperationsCount');
+//        }
+//      }
+//    }.property('App.router.currentState.parentState.name', 'App.router.mainHostDetailsController.hostOperationsCount'),
 
 
     templateName: require('templates/main/menu_item')
     templateName: require('templates/main/menu_item')
   })
   })

+ 2 - 3
ambari-web/app/views/main/service/info/menu.js

@@ -23,9 +23,8 @@ App.MainServiceInfoMenuView = Em.CollectionView.extend({
   classNames: ["nav", "nav-tabs"],
   classNames: ["nav", "nav-tabs"],
   content:[
   content:[
     { label:'Summary', routing:'summary', active:"active"},
     { label:'Summary', routing:'summary', active:"active"},
-    { label:'Metrics', routing:'metrics'},
-    { label:'Configs', routing:'configs'},
-    { label:'Audit', routing:'audit'}
+    { label:'Configs', routing:'configs'}/*,
+    { label:'Audit', routing:'audit'}*/
   ],
   ],
 
 
   init: function(){ this._super(); this.activateView(); },
   init: function(){ this._super(); this.activateView(); },

+ 2 - 2
ambari-web/app/views/installer/step10_view.js → ambari-web/app/views/wizard/step10_view.js

@@ -19,9 +19,9 @@
 
 
 var App = require('app');
 var App = require('app');
 
 
-App.InstallerStep10View = Em.View.extend({
+App.WizardStep10View = Em.View.extend({
 
 
-  templateName: require('templates/installer/step10'),
+  templateName: require('templates/wizard/step10'),
 
 
   didInsertElement: function () {
   didInsertElement: function () {
     var controller = this.get('controller');
     var controller = this.get('controller');

+ 6 - 3
ambari-web/app/views/wizard/step5_view.js

@@ -27,9 +27,12 @@ App.WizardStep5View = Em.View.extend({
     var controller = this.get('controller');
     var controller = this.get('controller');
     controller.loadStep();
     controller.loadStep();
 
 
-    var ZooKeeper = controller.lastZooKeeper();
-    if (ZooKeeper) {
-      ZooKeeper.set('showAddControl', true);
+    if (controller.lastZooKeeper()) {
+      if (controller.get("selectedServicesMasters").filterProperty("component_name", "ZooKeeper").length < controller.get("hosts.length")) {
+        controller.lastZooKeeper().set('showAddControl', true);
+      } else {
+        controller.lastZooKeeper().set('showRemoveControl', false);
+      }
     }
     }
   }
   }
 
 

+ 40 - 0
ambari-web/app/views/wizard/step6_view.js

@@ -25,7 +25,47 @@ App.WizardStep6View = Em.View.extend({
 
 
   didInsertElement: function () {
   didInsertElement: function () {
     var controller = this.get('controller');
     var controller = this.get('controller');
+    this.setLabel();
+    $('body').tooltip({
+      selector: '[rel=tooltip]'
+    });
     controller.loadStep();
     controller.loadStep();
+  },
+
+  setLabel: function () {
+    var label = Em.I18n.t('installer.step6.body');
+    var clients = this.get('controller.content.clients');
+    clients.forEach(function (_client) {
+      if (clients.length === 1) {
+        label = label + ' ' + _client.display_name;
+      } else if (_client !== clients[clients.length - 1]) {           // [clients.length - 1]
+        label = label + ' ' + _client.display_name;
+        if(_client !== clients[clients.length - 2]) {
+          label = label + ',';
+  }
+      } else {
+        label = label + ' and ' + _client.display_name + '.';
+      }
+    }, this);
+    this.set('label', label);
   }
   }
+});
+
+App.WizardStep6HostView = Em.View.extend({
 
 
+  host: null,
+  tagName: 'td',
+
+  didInsertElement: function () {
+    var components = this.get('controller').getMasterComponentsForHost(this.get('host.hostname'));
+    if(components){
+      components = components.join(" /\n");
+      this.$().popover({
+        title: 'master components hosted on ' + this.get('host.hostname'),
+        content: components,
+        placement: 'right',
+        trigger: 'hover'
+      });
+    }
+  }
 });
 });