You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jg...@apache.org on 2018/05/07 19:23:47 UTC

[ambari] branch branch-feature-AMBARI-14714 updated: Fix Add Host wizard.

This is an automated email from the ASF dual-hosted git repository.

jgolieb pushed a commit to branch branch-feature-AMBARI-14714
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714 by this push:
     new e9dcb10  Fix Add Host wizard.
e9dcb10 is described below

commit e9dcb10c8a2cd67dbc96996102472cca493035a9
Author: Jason Golieb <jg...@hortonworks.com>
AuthorDate: Mon May 7 14:56:49 2018 -0400

    Fix Add Host wizard.
---
 ambari-web/app/controllers/installer.js            |  21 -
 .../app/controllers/main/host/add_controller.js    |  10 -
 ambari-web/app/controllers/wizard.js               |  27 +
 .../app/controllers/wizard/step2_controller.js     |  26 +-
 .../app/controllers/wizard/step6_controller.js     | 245 --------
 .../app/controllers/wizard/step8_controller.js     | 139 +++--
 ambari-web/app/models/stack_service.js             |   2 +-
 ambari-web/app/routes/add_host_routes.js           |  24 +-
 ambari-web/app/routes/add_service_routes.js        |  34 +-
 ambari-web/app/routes/installer.js                 |  38 +-
 ambari-web/app/styles/wizard.less                  |   7 +
 ambari-web/app/templates/wizard/step2.hbs          |   3 +-
 ambari-web/app/templates/wizard/step6.hbs          |   7 +-
 ambari-web/app/templates/wizard/step8.hbs          |  46 +-
 ambari-web/app/utils/ajax/ajax.js                  |   4 +
 ambari-web/app/views/wizard/step6_view.js          |   1 -
 ambari-web/test/controllers/wizard/step6_test.js   | 656 ---------------------
 ambari-web/test/controllers/wizard/step8_test.js   |  22 +-
 .../mixins/common/configs/configs_saver_test.js    |   5 +
 ambari-web/test/views/wizard/step6_view_test.js    |   6 -
 20 files changed, 226 insertions(+), 1097 deletions(-)

diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index 0fe9dc0..c4bc072 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -1165,27 +1165,6 @@ App.InstallerController = App.WizardController.extend(App.Persist, {
     return dfd.promise();
   },
 
-  getStepSavedState: function (stepName) {
-    const stepIndex = this.getStepIndex(stepName);
-    const stepsSaved = this.get('content.stepsSavedState');
-
-    if (!!stepIndex && stepsSaved && stepsSaved[stepIndex]) {
-      return true;
-    }
-
-    return false;
-  },
-
-  setStepUnsaved: function (stepName) {
-    const stepIndex = this.getStepIndex(stepName);
-    const oldState = this.get('content.stepsSavedState') || {};
-    const newState = Em.Object.create(oldState);
-    newState[stepIndex] = false;
-
-    this.set('content.stepsSavedState', newState);
-    this.save('stepsSavedState');
-  },
-
   /**
    * Updates the stepsSaved array based on the stepName provided.
    * If the passed step is already saved, then nothing is changed.
diff --git a/ambari-web/app/controllers/main/host/add_controller.js b/ambari-web/app/controllers/main/host/add_controller.js
index bd528f2..2d8ade3 100644
--- a/ambari-web/app/controllers/main/host/add_controller.js
+++ b/ambari-web/app/controllers/main/host/add_controller.js
@@ -123,12 +123,6 @@ App.AddHostController = App.WizardController.extend({
       wizardControllerName: this.get('name'),
       localdb: App.db.data
     });
-    var self = this;
-    Em.run.next(function(){
-      if (self.isConfigGroupsEmpty()) {
-        self.disableStep(4);
-      }
-    });   
   },
 
   /**
@@ -152,10 +146,6 @@ App.AddHostController = App.WizardController.extend({
     this.setDBProperty('hosts', dbHosts);
   },
 
-  disableStep: function(step) {
-    this.get('isStepDisabled').findProperty('step', step).set('value', true);
-  },
-
   isConfigGroupsEmpty: function() {
     return !this.get('content.configGroups') || !this.get('content.configGroups').length; 
   },
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index 84ee966..499c5ef 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -343,6 +343,27 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
     return name;
   },
 
+  getStepSavedState: function (stepName) {
+    const stepIndex = this.getStepIndex(stepName);
+    const stepsSaved = this.get('content.stepsSavedState');
+
+    if (!!stepIndex && stepsSaved && stepsSaved[stepIndex]) {
+      return true;
+    }
+
+    return false;
+  },
+
+  setStepUnsaved: function (stepName) {
+    const stepIndex = this.getStepIndex(stepName);
+    const oldState = this.get('content.stepsSavedState') || {};
+    const newState = Em.Object.create(oldState);
+    newState[stepIndex] = false;
+
+    this.set('content.stepsSavedState', newState);
+    this.save('stepsSavedState');
+  },
+  
   /**
    * Move user to the selected step
    *
@@ -353,6 +374,12 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   gotoStep: function (stepName, disableNaviWarning) {
     const step = this.getStepIndex(stepName);
 
+    //in case stepName is a legacy number convert it to the
+    //legacy naming convention, a string starting with "step"
+    if (typeof stepName !== "string") {
+      stepName = "step" + stepName.toString();
+    }
+
     if (step === -1 || this.get('isStepDisabled').findProperty('step', step).get('value') !== false) {
       return false;
     }
diff --git a/ambari-web/app/controllers/wizard/step2_controller.js b/ambari-web/app/controllers/wizard/step2_controller.js
index 7caa3c6..25f663a 100644
--- a/ambari-web/app/controllers/wizard/step2_controller.js
+++ b/ambari-web/app/controllers/wizard/step2_controller.js
@@ -238,12 +238,20 @@ App.WizardStep2Controller = App.WizardStepController.extend({
           self = this;
     if (response.items.length > 0) {
       response.items.forEach(function (item, indx) {
+        const getFreeSpace = host => {
+          if (host.disk_info.length > 0) {
+            return (parseFloat(host.disk_info[0].available) / (1024 * 1024)).toFixed(2) + " GB";
+          }
+
+          return Em.I18n.t('common.unknown');
+        }
+
         installedHosts.push(Em.Object.create({
           'controller': self,
           'hostName': item.Hosts.host_name,
           'cpuCount': item.Hosts.cpu_count,
           'memory': (parseFloat(item.Hosts.total_mem) / (1024 * 1024)).toFixed(2) + " GB",
-          'freeSpace': (parseFloat(item.Hosts.disk_info[0].available) / (1024 * 1024)).toFixed(2) + " GB",
+          'freeSpace': getFreeSpace(item.Hosts),
           'isVisible': true,
 
           filterRow: function() {
@@ -634,8 +642,20 @@ App.WizardStep2Controller = App.WizardStepController.extend({
       }
     }
 
-    //this.set('content.installOptions.hostNames', this.get('hostNameArr'));
-    this.set('content.hosts', $.extend(hosts, this.getHostInfo()));
+    //add newly registered hosts
+    const newHosts = this.getHostInfo();
+    if (hosts) {
+      for (let hostName in newHosts) {
+        if (!hosts[hostName]) {
+          hosts[hostName] = newHosts[hostName];
+        }
+      }
+    } else {
+      hosts = newHosts;
+    }
+
+    this.set('content.hosts', hosts);
+
     this.setAmbariJavaHome();
   },
 
diff --git a/ambari-web/app/controllers/wizard/step6_controller.js b/ambari-web/app/controllers/wizard/step6_controller.js
index 3d7bff5..3f0b2d7 100644
--- a/ambari-web/app/controllers/wizard/step6_controller.js
+++ b/ambari-web/app/controllers/wizard/step6_controller.js
@@ -238,7 +238,6 @@ App.WizardStep6Controller = App.WizardStepController.extend(App.HostComponentVal
     var name = Em.get(event, 'context.name');
     if (name) {
       this.setAllNodes(name, true);
-      this.callValidation();
     }
   },
 
@@ -251,7 +250,6 @@ App.WizardStep6Controller = App.WizardStepController.extend(App.HostComponentVal
     var name = Em.get(event, 'context.name');
     if (name) {
       this.setAllNodes(name, false);
-      this.callValidation();
     }
   },
 
@@ -351,8 +349,6 @@ App.WizardStep6Controller = App.WizardStepController.extend(App.HostComponentVal
     this.render();
     if (this.get('content.skipSlavesStep')) {
       App.router.send('next');
-    } else {
-      this.callValidation();
     }
   },
 
@@ -630,246 +626,5 @@ App.WizardStep6Controller = App.WizardStepController.extend(App.HostComponentVal
    */
   getMasterComponentsForHost: function (hostName) {
     return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component');
-  },
-
-  callValidation: function (successCallback) {
-    var self = this;
-    var validationCallback = function() {
-      self.set('validationInProgress', false);
-      if (App.get('router.btnClickInProgress') && successCallback) {
-        successCallback();
-      }
-    };
-    clearTimeout(this.get('timer'));
-    if (this.get('validationInProgress')) {
-      this.set('timer', setTimeout(function () {
-        self.callValidation();
-      }, 700));
-    } else {
-      this.callServerSideValidation()
-        .then(validationCallback);
-    }
-  },
-
-  /**
-   * Update submit button status
-   * @method callServerSideValidation
-   */
-  callServerSideValidation: function (successCallback) {
-    this.set('validationInProgress', true);
-
-    var selectedServices = App.StackService.find().filterProperty('isSelected').mapProperty('serviceName');
-    var installedServices = App.StackService.find().filterProperty('isInstalled').mapProperty('serviceName');
-    var services = installedServices.concat(selectedServices).uniq();
-    var hostNames = this.getAllHosts().mapProperty('hostName');
-
-    var bluePrintsForValidation = this.getValidationBlueprint();
-    this.set('content.recommendationsHostGroups', bluePrintsForValidation);
-
-    //TODO - mpacks: Hard coded to use first mpack. Update when we are installing multiple mpacks.
-    const selectedMpacks = this.get('content.selectedMpacks');
-
-    return this.validateSelectedHostComponents({
-      services: services,
-      hosts: hostNames,
-      stackName: selectedMpacks[0].name,
-      stackVersion: selectedMpacks[0].version,
-      blueprint: bluePrintsForValidation
-    });
-  },
-
-  /**
-   * Returns blueprint passed to validation request
-   * @method getValidationBlueprint
-   */
-  getValidationBlueprint: function() {
-    var slaveBlueprint = this.getCurrentBlueprint();
-    var masterBlueprint = null;
-    var invisibleInstalledMasters = [];
-    var hostNames = this.getAllHosts().mapProperty('hostName');
-    var invisibleSlavesAndClients = App.StackServiceComponent.find().filter(function (component) {
-      return component.get("isSlave") && component.get("isShownOnInstallerSlaveClientPage") === false ||
-        component.get("isClient") && component.get("isRequiredOnAllHosts");
-    }).mapProperty("componentName");
-    //Existing Installed but invisible masters on `Assign Masters page` should be included in host component layout for recommnedation/validation call
-    if (this.get('isAddServiceWizard')) {
-      var invisibleMasters = App.StackServiceComponent.find().filterProperty("isMaster").filterProperty("isShownOnAddServiceAssignMasterPage", false);
-      invisibleInstalledMasters = invisibleMasters.filter(function(item){
-        var masterComponent = App.MasterComponent.find().findProperty('componentName', item.get('componentName'));
-        return masterComponent && !!masterComponent.get('totalCount');
-      }).mapProperty("componentName");
-    }
-    if (this.get('isInstallerWizard') || this.get('isAddServiceWizard')) {
-      masterBlueprint = this.getCurrentMastersBlueprint();
-      var selectedClientComponents = this.get('content.clients').mapProperty('component_name');
-      var alreadyInstalledClients = App.get('components.clients').reject(function (c) {
-        return selectedClientComponents.contains(c);
-      });
-      var invisibleComponents = invisibleInstalledMasters.concat(invisibleSlavesAndClients).concat(alreadyInstalledClients);
-      var invisibleBlueprint = blueprintUtils.filterByComponents(this.get('content.recommendations'), invisibleComponents);
-      masterBlueprint = blueprintUtils.mergeBlueprints(masterBlueprint, invisibleBlueprint);
-    } else if (this.get('isAddHostWizard')) {
-      masterBlueprint = this.getCurrentMasterSlaveBlueprint();
-      hostNames = hostNames.concat(App.Host.find().mapProperty("hostName")).uniq();
-      slaveBlueprint = blueprintUtils.addComponentsToBlueprint(slaveBlueprint, invisibleSlavesAndClients);
-    }
-    return blueprintUtils.mergeBlueprints(masterBlueprint, slaveBlueprint);
-  },
-
-  /**
-   * Success-callback for validations request
-   * @param {object} data
-   * @method updateValidationsSuccessCallback
-   * @override App.HostComponentRecommendationMixin
-   */
-  updateValidationsSuccessCallback: function (data) {
-    var clientComponents = App.get('components.clients');
-
-    this.set('generalErrorMessages', []);
-    this.set('generalWarningMessages', []);
-    this.get('hosts').setEach('warnMessages', []);
-    this.get('hosts').setEach('errorMessages', []);
-    this.get('hosts').setEach('anyMessage', false);
-    this.get('hosts').forEach(function (host) {
-      host.checkboxes.setEach('hasWarnMessage', false);
-      host.checkboxes.setEach('hasErrorMessage', false);
-    });
-    var anyGeneralClientErrors = false; // any error/warning for any client component (under "CLIENT" alias)
-
-    var validationData = validationUtils.filterNotInstalledComponents(data);
-    validationData.filterProperty('type', 'host-component').filter(function (i) {
-      return !(i['component-name'] && App.StackServiceComponent.find().findProperty('componentName', i['component-name']).get('isMaster'));
-    }).forEach(function (item) {
-      var checkboxWithIssue = null;
-      var isGeneralClientValidationItem = clientComponents.contains(item['component-name']); // it is an error/warning for any client component (under "CLIENT" alias)
-      var host = this.get('hosts').find(function (h) {
-        return h.hostName === item.host && h.checkboxes.some(function (checkbox) {
-          var isClientComponent = checkbox.component === "CLIENT" && isGeneralClientValidationItem;
-          if (checkbox.component === item['component-name'] || isClientComponent) {
-            checkboxWithIssue = checkbox;
-            return true;
-          }
-          return false;
-        });
-      });
-      if (host) {
-        Em.set(host, 'anyMessage', true);
-
-        if (item.level === 'ERROR') {
-          host.errorMessages.pushObject(item.message);
-          Em.set(checkboxWithIssue, 'hasErrorMessage', true);
-        }
-        else
-          if (item.level === 'WARN') {
-            host.warnMessages.pushObject(item.message);
-            Em.set(checkboxWithIssue, 'hasWarnMessage', true);
-          }
-      }
-      else {
-        var componentHeader = this.get('headers').findProperty('name', item['component-name']);
-        if (componentHeader && componentHeader.get('isDisabled')) {
-          // skip validation messages for components which disabled for editing
-          return;
-        }
-        var component;
-        if (isGeneralClientValidationItem) {
-          if (!anyGeneralClientErrors) {
-            anyGeneralClientErrors = true;
-            component = "Client";
-          }
-        }
-        else {
-          component = item['component-name'];
-        }
-
-        if (component || !item['component-name']) {
-          var details = "";
-          if (item.host) {
-            details += " (" + item.host + ")";
-          }
-
-          if (item.level === 'ERROR') {
-            this.get('generalErrorMessages').push(item.message + details);
-          }
-          else
-            if (item.level === 'WARN') {
-              this.get('generalWarningMessages').push(item.message + details);
-            }
-        }
-      }
-    }, this);
-  },
-
-  /**
-   * Error-callback for validations request
-   * @param {object} jqXHR
-   * @param {object} ajaxOptions
-   * @param {string} error
-   * @param {object} opt
-   * @method updateValidationsErrorCallback
-   * @override App.HostComponentRecommendationMixin
-   */
-  updateValidationsErrorCallback: function (jqXHR, ajaxOptions, error, opt) {
-  },
-
-  /**
-   * Composes selected values of comboboxes into blueprint format
-   */
-  getCurrentBlueprint: function () {
-    var clientComponents = this.get('content.clients').mapProperty('component_name');
-    var components = this.get('hosts').reduce(function(acc, host) {
-      var checked = host.checkboxes.filterProperty('checked', true).mapProperty('component');
-      var componentNames = checked.indexOf('CLIENT') > -1 ? checked.without('CLIENT').concat(clientComponents) : checked;
-      return acc.concat(componentNames.map(function(componentName) {
-        return Em.Object.create({
-          componentName: componentName,
-          hostName: Em.get(host, 'hostName')
-        });
-      }));
-    }, []);
-    return this.getComponentsBlueprint(components);
-  },
-
-  /**
-   * Create blueprint from assigned master components to appropriate hosts
-   * @returns {Object}
-   * @method getCurrentMastersBlueprint
-   */
-  getCurrentMastersBlueprint: function () {
-    var masters = this.get('content.masterComponentHosts');
-    var mastersBlueprint = this.getComponentsBlueprint(masters.map(function(component) {
-      var c = Em.Object.create(component);
-      c.set('componentName', c.get('component'));
-      return c;
-    }), this.get('hosts').mapProperty('hostName'));
-    return blueprintUtils.mergeBlueprints(mastersBlueprint, this.getCurrentSlaveBlueprint());
-  },
-
-  /**
-   * In case of any validation issues shows accept dialog box for user which allow cancel and fix issues or continue anyway
-   * @metohd submit
-   */
-  showValidationIssuesAcceptBox: function(callback) {
-    var self = this;
-
-    if (self.get('anyWarnings') || self.get('anyErrors')) {
-      App.ModalPopup.show({
-        'data-qa': 'validation-issues-modal',
-        primary: Em.I18n.t('common.continueAnyway'),
-        header: Em.I18n.t('installer.step6.validationIssuesAttention.header'),
-        body: Em.I18n.t('installer.step6.validationIssuesAttention'),
-        primaryClass: 'btn-danger',
-        onPrimary: function () {
-          this.hide();
-          callback();
-        },
-        onSecondary: function () {
-          App.set('router.nextBtnClickInProgress', false);
-          this._super();
-        }
-      });
-    } else {
-      callback();
-    }
   }
 });
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js
index 9a894eb..0ba11c9 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -43,6 +43,15 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
   isInstaller: Em.computed.equal('content.controllerName', 'installerController'),
 
   /**
+   * Indicates whether to show the repo info section of the summary.
+   * Don't need to show this for Add Host in 3.0 because we are not
+   * letting the user change repos when installing slave/client components.
+   * 
+   * @type {boolean}
+   */
+  showRepoInfo: Em.computed.or('isInstaller', 'isAddService'),
+
+  /**
    * List of raw data about cluster that should be displayed
    * @type {Array}
    */
@@ -96,7 +105,6 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
     return !!App.get('router.mainAdminKerberosController.kdc_type')
   }.property('App.router.mainAdminKerberosController.kdc_type'),
 
-
   /**
    * Should Submit button be disabled
    * @type {bool}
@@ -141,7 +149,7 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
   configGroups: [],
 
   selectedServices: function () {
-    const services = App.StackService.find().map(service => service);
+    const services = App.StackService.find().filter(service => service.get('isSelected') === true && service.get('isInstalled') === false);
     return services;
   }.property(),
 
@@ -305,7 +313,7 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
     this.get('clusterInfo').pushObject(Em.Object.create(totalHostsObj));
 
     //repo
-    if (this.get('isAddService') || this.get('isAddHost')) {
+    if (this.get('isAddService')) {
       // For some stacks there is no info regarding stack versions to upgrade, e.g. HDP-2.1
       if (App.StackVersion.find().get('content.length')) {
         this.loadRepoInfo();
@@ -313,44 +321,46 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
         this.loadDefaultRepoInfo();
       }
     } else {
-      // from install wizard
-      var downloadConfig = this.get('downloadConfig');
-      var allRepos = [];
-      var selectedMpacks = this.get('content.selectedMpacks');
-      var registeredMpacks = this.get('content.registeredMpacks');
-      if (selectedMpacks && registeredMpacks) {
-        selectedMpacks.forEach(mpack => {
-          if (mpack.operatingSystems) { //repos have been customized
-            mpack.operatingSystems.forEach(os => {
-              if (os.selected) {
-                os.repos.forEach(function (repo) {
-                  allRepos.push(Em.Object.create({
-                    base_url: repo.downloadUrl,
-                    os_type: os.type,
-                    repo_id: repo.repoId
-                  }));
-                });
-              }
-            })
-          } else { //repos have not been customized, so use default info
-            const rmp = registeredMpacks.find(rmp => rmp.MpackInfo.mpack_name === mpack.name && rmp.MpackInfo.mpack_version === mpack.version);
-            if (rmp) {
-              rmp.operating_systems.forEach(os => {
-                os.OperatingSystems.repositories.forEach(function (repo) {
-                  allRepos.push(Em.Object.create({
-                    base_url: repo.base_url,
-                    os_type: repo.os_type,
-                    repo_id: repo.repo_id
-                  }));
+      if (this.get('isInstaller')) {
+        // from install wizard
+        var downloadConfig = this.get('downloadConfig');
+        var allRepos = [];
+        var selectedMpacks = this.get('content.selectedMpacks');
+        var registeredMpacks = this.get('content.registeredMpacks');
+        if (selectedMpacks && registeredMpacks) {
+          selectedMpacks.forEach(mpack => {
+            if (mpack.operatingSystems) { //repos have been customized
+              mpack.operatingSystems.forEach(os => {
+                if (os.selected) {
+                  os.repos.forEach(function (repo) {
+                    allRepos.push(Em.Object.create({
+                      base_url: repo.downloadUrl,
+                      os_type: os.type,
+                      repo_id: repo.repoId
+                    }));
+                  });
+                }
+              })
+            } else { //repos have not been customized, so use default info
+              const rmp = registeredMpacks.find(rmp => rmp.MpackInfo.mpack_name === mpack.name && rmp.MpackInfo.mpack_version === mpack.version);
+              if (rmp) {
+                rmp.operating_systems.forEach(os => {
+                  os.OperatingSystems.repositories.forEach(function (repo) {
+                    allRepos.push(Em.Object.create({
+                      base_url: repo.base_url,
+                      os_type: repo.os_type,
+                      repo_id: repo.repo_id
+                    }));
+                  })
                 })
-              })  
+              }
             }
-          }
-        });
-      }  
-      allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName"));
-      this.get('clusterInfo').set('useRedhatSatellite', downloadConfig.useRedhatSatellite);
-      this.get('clusterInfo').set('repoInfo', allRepos);
+          });
+        }
+        allRepos.set('display_name', Em.I18n.t("installer.step8.repoInfo.displayName"));
+        this.get('clusterInfo').set('useRedhatSatellite', downloadConfig.useRedhatSatellite);
+        this.get('clusterInfo').set('repoInfo', allRepos);
+      }
     }
   },
 
@@ -460,21 +470,36 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
    * @method loadServices
    */
   loadServices: function () {
-    this.get('selectedServices').filterProperty('isHiddenOnSelectServicePage', false).forEach(function (service) {
+    let services;
+    
+    if (this.get('isAddHost')) {
+      services = this.get('installedServices');
+    } else {
+      services = this.get('selectedServices');
+    }
+
+    services.filterProperty('isHiddenOnSelectServicePage', false).forEach(function (service) {
       var serviceObj = Em.Object.create({
         service_name: service.get('serviceName'),
         display_name: service.get('displayNameOnSelectServicePage'),
         service_components: Em.A([])
       });
       service.get('serviceComponents').forEach(function (component) {
+        const isClient = component.get('isClient');
+        const isSlave = component.get('isSlave');
+        const isMaster = component.get('isMaster');
+
+        //skip master components in Add Host wizard, since that wizard only allows adding slaves/clients
+        if (isMaster && this.get('isAddHost')) return;
+
         // show clients for services that have only clients components
-        if ((component.get('isClient') || component.get('isRequiredOnAllHosts')) && !service.get('isClientOnlyService')) return;
+        if ((isClient || component.get('isRequiredOnAllHosts')) && !service.get('isClientOnlyService')) return;
         // no HA component
         if (component.get('isHAComponentOnly')) return;
         // skip if component is not allowed on single node cluster
         if (Object.keys(this.get('content.hosts')).length === 1 && component.get('isNotAllowedOnSingleNodeCluster')) return;
         var displayName;
-        if (component.get('isClient')) {
+        if (isClient) {
           displayName = Em.I18n.t('common.clients')
         } else {
           // remove service name from component display name
@@ -484,11 +509,10 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
         var componentName = component.get('componentName');
         var masterComponents = this.get('content.masterComponentHosts');
         var isMasterComponentSelected = masterComponents.someProperty('component', componentName);
-        var isMaster = component.get('isMaster');
-
+        
         if (!isMaster || isMasterComponentSelected) {
           serviceObj.get('service_components').pushObject(Em.Object.create({
-            component_name: component.get('isClient') ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'),
+            component_name: isClient ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'),
             display_name: displayName,
             component_value: this.assignComponentHosts(component)
           }));
@@ -504,7 +528,9 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
           }));
         }
       }
-      this.get('services').pushObject(serviceObj);
+      if (serviceObj.get('service_components').length > 0) {
+        this.get('services').pushObject(serviceObj);
+      }  
     }, this);
   },
 
@@ -1458,16 +1484,19 @@ App.WizardStep8Controller = App.WizardStepController.extend(App.AddSecurityConfi
   registerHostsToComponent: function (hostNames, componentName) {
     if (!hostNames.length) return;
 
-    let serviceName,
-        serviceGroupName;
-    var queryStr = '';
-    hostNames.forEach(function (hostName) {
-      queryStr += 'Hosts/host_name=' + hostName + '|';
-    });
-    //slice off last symbol '|'
-    queryStr = queryStr.slice(0, -1);
+    let serviceName;
+    let serviceGroupName;
+
+    const queryStr = `Hosts/host_name.in(${hostNames.join(',')})`;
+
+    let services;
+    if (this.get('isAddHost')) {
+      services = this.get('installedServices');
+    } else {
+      services = this.get('selectedServices');
+    }
 
-    this.get('selectedServices').forEach( function (service) {
+    services.forEach( function (service) {
       if (service.get('serviceComponents').findProperty('componentName', componentName)) {
         serviceName = service.get('serviceName');
         serviceGroupName = service.get('stackName');
diff --git a/ambari-web/app/models/stack_service.js b/ambari-web/app/models/stack_service.js
index c589d74..5f5eace 100644
--- a/ambari-web/app/models/stack_service.js
+++ b/ambari-web/app/models/stack_service.js
@@ -106,7 +106,7 @@ App.StackService = DS.Model.extend({
   stackVersion: DS.attr('string'),
   selection: DS.attr('string'),
   isMandatory: DS.attr('boolean', {defaultValue: false}),
-  isSelected: DS.attr('boolean', {defaultValue: true}),
+  isSelected: DS.attr('boolean', {defaultValue: false}),
   isInstalled: DS.attr('boolean', {defaultValue: false}),
   isInstallable: DS.attr('boolean', {defaultValue: true}),
   isServiceWithWidgets: DS.attr('boolean', {defaultValue: false}),
diff --git a/ambari-web/app/routes/add_host_routes.js b/ambari-web/app/routes/add_host_routes.js
index 0158269..d98a9ca 100644
--- a/ambari-web/app/routes/add_host_routes.js
+++ b/ambari-web/app/routes/add_host_routes.js
@@ -192,20 +192,16 @@ module.exports = App.WizardRoute.extend({
       var addHostController = router.get('addHostController');
       var wizardStep6Controller = router.get('wizardStep6Controller');
 
-      wizardStep6Controller.callValidation(function () {
-        wizardStep6Controller.showValidationIssuesAcceptBox(function () {
-          addHostController.saveSlaveComponentHosts(wizardStep6Controller);
-          if (wizardStep6Controller.isAllCheckboxesEmpty()) {
-            App.set('router.nextBtnClickInProgress', false);
-            router.transitionTo('step5');
-            addHostController.set('content.configGroups', []);
-            addHostController.saveServiceConfigGroups();
-          } else {
-            App.set('router.nextBtnClickInProgress', false);
-            router.transitionTo('step4');
-          }
-        });
-      });
+      addHostController.saveSlaveComponentHosts(wizardStep6Controller);
+      if (wizardStep6Controller.isAllCheckboxesEmpty()) {
+        App.set('router.nextBtnClickInProgress', false);
+        router.transitionTo('step5');
+        addHostController.set('content.configGroups', []);
+        addHostController.saveServiceConfigGroups();
+      } else {
+        App.set('router.nextBtnClickInProgress', false);
+        router.transitionTo('step4');
+      }
     }
   }),
 
diff --git a/ambari-web/app/routes/add_service_routes.js b/ambari-web/app/routes/add_service_routes.js
index 4120da7..7f6a05f 100644
--- a/ambari-web/app/routes/add_service_routes.js
+++ b/ambari-web/app/routes/add_service_routes.js
@@ -219,26 +219,22 @@ module.exports = App.WizardRoute.extend({
       var addServiceController = router.get('addServiceController');
       var wizardStep6Controller = router.get('wizardStep6Controller');
 
-      wizardStep6Controller.callValidation(function () {
-        wizardStep6Controller.showValidationIssuesAcceptBox(function () {
-          addServiceController.saveSlaveComponentHosts(wizardStep6Controller);
-          addServiceController.get('content').set('serviceConfigProperties', null);
-          addServiceController.setDBProperties({
-            groupsToDelete: null,
-            recommendationsHostGroups: wizardStep6Controller.get('content.recommendationsHostGroups'),
-            recommendationsConfigs: null
-          });
-          router.get('wizardStep7Controller').set('recommendationsConfigs', null);
-          router.get('wizardStep7Controller').clearAllRecommendations();
-          addServiceController.setDBProperty('serviceConfigGroups', undefined);
-          App.ServiceConfigGroup.find().clear();
-          addServiceController.clearServiceConfigProperties();
-          if (App.get('isKerberosEnabled')) {
-            addServiceController.setDBProperty('kerberosDescriptorConfigs', null);
-          }
-          router.transitionTo('step4');
-        });
+      addServiceController.saveSlaveComponentHosts(wizardStep6Controller);
+      addServiceController.get('content').set('serviceConfigProperties', null);
+      addServiceController.setDBProperties({
+        groupsToDelete: null,
+        recommendationsHostGroups: wizardStep6Controller.get('content.recommendationsHostGroups'),
+        recommendationsConfigs: null
       });
+      router.get('wizardStep7Controller').set('recommendationsConfigs', null);
+      router.get('wizardStep7Controller').clearAllRecommendations();
+      addServiceController.setDBProperty('serviceConfigGroups', undefined);
+      App.ServiceConfigGroup.find().clear();
+      addServiceController.clearServiceConfigProperties();
+      if (App.get('isKerberosEnabled')) {
+        addServiceController.setDBProperty('kerberosDescriptorConfigs', null);
+      }
+      router.transitionTo('step4');
     }
   }),
 
diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js
index 03171d2..e692873 100644
--- a/ambari-web/app/routes/installer.js
+++ b/ambari-web/app/routes/installer.js
@@ -653,27 +653,25 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
       var controller = router.get('installerController');
       var wizardStep6Controller = router.get('wizardStep6Controller');
       if (!wizardStep6Controller.get('submitDisabled')) {
-        wizardStep6Controller.showValidationIssuesAcceptBox(function () {
-          if (!router.get('btnClickInProgress')) {
-            App.set('router.nextBtnClickInProgress', true);
-            controller.saveSlaveComponentHosts(wizardStep6Controller);
-            controller.get('content').set('serviceConfigProperties', null);
-            controller.get('content').set('componentsFromConfigs', []);
-            // Clear subsequent steps if user made changes
-            if (!wizardStep6Controller.get('isSaved')) {
-              controller.setDBProperties({
-                serviceConfigGroups: null,
-                recommendationsHostGroups: wizardStep6Controller.get('content.recommendationsHostGroups'),
-                recommendationsConfigs: null,
-                componentsFromConfigs: []
-              });
-              controller.clearServiceConfigProperties();
-            }
-            controller.setStepSaved('step6');
-            router.transitionTo('step7');
-            console.timeEnd('step6 next');
+        if (!router.get('btnClickInProgress')) {
+          App.set('router.nextBtnClickInProgress', true);
+          controller.saveSlaveComponentHosts(wizardStep6Controller);
+          controller.get('content').set('serviceConfigProperties', null);
+          controller.get('content').set('componentsFromConfigs', []);
+          // Clear subsequent steps if user made changes
+          if (!wizardStep6Controller.get('isSaved')) {
+            controller.setDBProperties({
+              serviceConfigGroups: null,
+              recommendationsHostGroups: wizardStep6Controller.get('content.recommendationsHostGroups'),
+              recommendationsConfigs: null,
+              componentsFromConfigs: []
+            });
+            controller.clearServiceConfigProperties();
           }
-        });
+          controller.setStepSaved('step6');
+          router.transitionTo('step7');
+          console.timeEnd('step6 next');
+        }
       }
     }
   }),
diff --git a/ambari-web/app/styles/wizard.less b/ambari-web/app/styles/wizard.less
index 5a0e67b..638560c 100644
--- a/ambari-web/app/styles/wizard.less
+++ b/ambari-web/app/styles/wizard.less
@@ -356,6 +356,13 @@
           border-top-color: #eee;
           border-bottom: 1px solid #eee;
         }
+        th.freeze {
+          //Added this because due to its absolute positioning, 
+          //the frozen column header was overlapping and blocking
+          //the next column header from being clicked, and that one
+          //contains the "all | none" links for checkbox selections.
+          pointer-events: none;
+        }
         td.freeze {
           padding-bottom: 11px;
         }
diff --git a/ambari-web/app/templates/wizard/step2.hbs b/ambari-web/app/templates/wizard/step2.hbs
index e5e1348..b465ef2 100644
--- a/ambari-web/app/templates/wizard/step2.hbs
+++ b/ambari-web/app/templates/wizard/step2.hbs
@@ -211,8 +211,7 @@
       </div>
       {{#if isAddHostWizard}}
         <br>
-        {{view view.skipHostsCheckBox checkedBinding="content.installOptions.skipHostChecks"}}
-        {{t installer.step2.skipHostChecks.label}}
+        {{view view.skipHostsCheckBox checkedBinding="content.installOptions.skipHostChecks" labelTranslate="installer.step2.skipHostChecks.label"}}
       {{/if}}
     </div>
   </div>
diff --git a/ambari-web/app/templates/wizard/step6.hbs b/ambari-web/app/templates/wizard/step6.hbs
index b012b8a..aba9b8e 100644
--- a/ambari-web/app/templates/wizard/step6.hbs
+++ b/ambari-web/app/templates/wizard/step6.hbs
@@ -60,10 +60,9 @@
             <th class="host-column freeze">{{t common.host}}</th>
             {{#each header in controller.headers}}
               <th {{bindAttr class="header.name"}}>
-                <a href="#" {{QAAttr "select-all"}} {{bindAttr class="header.allChecked:selected:deselected header.isDisabled:remove-link" id="header.allId"}}
-                  {{action "selectAllNodes" header target="controller"}}>{{t all}}</a> &nbsp;|&nbsp; <a
-                {{QAAttr "deselect-all"}} href="#" {{bindAttr class="header.noChecked:selected:deselected header.isDisabled:remove-link" id="header.noneId"}}
-                {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a>
+                <a href="#" {{QAAttr "select-all"}} {{bindAttr class="header.allChecked:selected:deselected header.isDisabled:remove-link" id="header.allId"}} {{action "selectAllNodes" header target="controller"}}>{{t all}}</a>
+                &nbsp;|&nbsp;
+                <a href="#" {{QAAttr "deselect-all"}} {{bindAttr class="header.noChecked:selected:deselected header.isDisabled:remove-link" id="header.noneId"}} {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a>
               </th>
             {{/each}}
           </tr>
diff --git a/ambari-web/app/templates/wizard/step8.hbs b/ambari-web/app/templates/wizard/step8.hbs
index ce160ec..c81315d 100644
--- a/ambari-web/app/templates/wizard/step8.hbs
+++ b/ambari-web/app/templates/wizard/step8.hbs
@@ -35,30 +35,32 @@
             </p>
           {{/each}}
 
-          <p><b>{{controller.clusterInfo.repoInfo.display_name}}</b>:</p>
+          {{#if controller.showRepoInfo}}
+            <p><b>{{controller.clusterInfo.repoInfo.display_name}}</b>:</p>
 
-          {{#if controller.clusterInfo.useRedhatSatellite}}
-            <div>
-              <ul>
-                <li>
-                  <p>{{t installer.step1.advancedRepo.useRedhatSatellite.message}}</p>
-                </li>
-              </ul>
-            </div>
-          {{else}}
-            <div>
-              <ul>
-                {{#each item in controller.clusterInfo.repoInfo}}
+            {{#if controller.clusterInfo.useRedhatSatellite}}
+              <div>
+                <ul>
                   <li>
-                    <p><span class="text text-info">{{item.os_type}} ({{item.repo_id}}): <br/></span>{{item.base_url}}</p>
+                    <p>{{t installer.step1.advancedRepo.useRedhatSatellite.message}}</p>
                   </li>
-                {{/each}}
-              </ul>
-            </div>
+                </ul>
+              </div>
+            {{else}}
+              <div>
+                <ul>
+                  {{#each item in controller.clusterInfo.repoInfo}}
+                    <li>
+                      <p><span class="text text-info">{{item.os_type}} ({{item.repo_id}}): <br/></span>{{item.base_url}}</p>
+                    </li>
+                  {{/each}}
+                </ul>
+              </div>
+            {{/if}}
           {{/if}}
-
-          <div>
-            {{#if controller.services.length}}
+          
+          {{#if controller.services.length}}
+            <div>
               <p><b>{{t menu.item.services}}:</b></p>
               <ul>
                 {{#each controller.services}}
@@ -74,8 +76,8 @@
                   </li>
                 {{/each}}
               </ul>
-            {{/if}}
-          </div>
+            </div>
+          {{/if}}
         </div>
       </div>
     </div>
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 8a9ed87..78105ec 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -2502,6 +2502,10 @@ var urls = {
     }
   },
 
+  'components.get.staleConfigs': {
+    'real': "/clusters/{clusterName}/host_components?HostRoles/stale_configs=true"
+  },
+
   'restart.staleConfigs': {
     'real': "/clusters/{clusterName}/requests",
     'mock': "",
diff --git a/ambari-web/app/views/wizard/step6_view.js b/ambari-web/app/views/wizard/step6_view.js
index 225b16b..8713f2a 100644
--- a/ambari-web/app/views/wizard/step6_view.js
+++ b/ambari-web/app/views/wizard/step6_view.js
@@ -82,7 +82,6 @@ App.WizardStep6View = App.TableView.extend({
     var checkbox = e.context;
     Em.set(checkbox, 'checked', !checkbox.checked);
     this.get('controller').checkCallback(checkbox.component);
-    this.get('controller').callValidation();
     this.get('controller').hostsChanged();
   },
 
diff --git a/ambari-web/test/controllers/wizard/step6_test.js b/ambari-web/test/controllers/wizard/step6_test.js
index def651e..a43386f 100644
--- a/ambari-web/test/controllers/wizard/step6_test.js
+++ b/ambari-web/test/controllers/wizard/step6_test.js
@@ -93,19 +93,6 @@ describe('App.WizardStep6Controller', function () {
     });
   });
 
-  describe('#showValidationIssuesAcceptBox', function () {
-    it('should return true if success callback', function () {
-      var deffer = jQuery.Deferred();
-      function callback() {
-        deffer.resolve(true);
-      }
-      controller.showValidationIssuesAcceptBox(callback);
-      jQuery.when(deffer.promise()).then(function(data) {
-        expect(data).to.equal(true);
-      });
-    });
-  });
-
   describe('#selectAllNodes', function () {
 
     var hostsObj = Em.A([Em.Object.create({
@@ -595,132 +582,6 @@ describe('App.WizardStep6Controller', function () {
     });
   });
 
-  describe('#updateValidationsSuccessCallback', function () {
-
-    var hosts = Em.A([Em.Object.create({
-      warnMessages: "warn",
-      errorMessages: "error",
-      anyMessage: true,
-      checkboxes: Em.A([Em.Object.create({
-        hasWarnMessage: true,
-        hasErrorMessage: true
-      })])
-    })]);
-
-    var validationData = Em.Object.create({
-      resources: Em.A([
-        Em.Object.create({
-          items: Em.A([
-            Em.Object.create({
-              "component-name": 'HDFS_CLIENT',
-              host: "1",
-              isMaster: true
-            })
-          ])
-        })
-      ])
-    });
-
-    beforeEach(function () {
-      sinon.stub(validationUtils, 'filterNotInstalledComponents', function () {
-        return Em.A([Em.Object.create({
-              componentName: 'c0',
-              isSlave: true,
-              type: 'host-component',
-              level: 'ERROR'
-            }),
-            Em.Object.create({
-              componentName: 'c1',
-              isSlave: true,
-              type: 'host-component',
-              level: 'WARN',
-              isShownOnInstallerSlaveClientPage: true
-          })]);
-      });
-      sinon.stub(App.StackServiceComponent, 'find', function () {
-          return [
-            Em.Object.create({
-              componentName: 'c0',
-              isSlave: true
-            }),
-            Em.Object.create({
-              componentName: 'c1',
-              isSlave: true,
-              isShownOnInstallerSlaveClientPage: true
-            }),
-            Em.Object.create({
-              componentName: 'c2',
-              isSlave: true,
-              isShownOnInstallerSlaveClientPage: false
-            }),
-            Em.Object.create({
-              componentName: 'c3',
-              isClient: true
-            }),
-            Em.Object.create({
-              componentName: 'c4',
-              isClient: true,
-              isRequiredOnAllHosts: false
-            }),
-            Em.Object.create({
-              componentName: 'c5',
-              isClient: true,
-              isRequiredOnAllHosts: true
-            }),
-            Em.Object.create({
-              componentName: 'c6',
-              isMaster: true,
-              isShownOnInstallerAssignMasterPage: true
-            }),
-            Em.Object.create({
-              componentName: 'c7',
-              isMaster: true,
-              isShownOnInstallerAssignMasterPage: false
-            }),
-            Em.Object.create({
-              componentName: 'HDFS_CLIENT',
-              isMaster: true,
-              isShownOnAddServiceAssignMasterPage: true
-            }),
-            Em.Object.create({
-              componentName: 'c9',
-              isMaster: true,
-              isShownOnAddServiceAssignMasterPage: false
-            })
-          ];
-        });
-      controller.set('hosts', hosts);
-      controller.updateValidationsSuccessCallback(validationData);
-    });
-
-    afterEach(function () {
-      App.StackServiceComponent.find.restore();
-      validationUtils.filterNotInstalledComponents.restore();
-    });
-
-    it('no generalErrorMessages', function () {
-      expect(controller.get('generalErrorMessages').length).to.equal(0);
-    });
-
-    it('no generalWarningMessages', function () {
-      expect(controller.get('generalWarningMessages').length).to.equal(0);
-    });
-
-    it('hosts info is valid', function () {
-      var cHosts = JSON.parse(JSON.stringify(controller.get('hosts')));
-      var expected = [{
-        warnMessages: [null],
-        errorMessages: [null],
-        anyMessage: true,
-        checkboxes: [{
-          hasWarnMessage: true,
-          hasErrorMessage: true
-        }]
-      }];
-      expect(cHosts).to.eql(expected);
-    });
-  });
-
   describe('#clearError', function () {
 
     var headers = Em.A([
@@ -1142,521 +1003,6 @@ describe('App.WizardStep6Controller', function () {
     });
   });
 
-  describe('#getCurrentMastersBlueprint', function () {
-    var tests = Em.A([
-      {
-        masterComponentHosts: Em.A([
-          {hostName: 'h1', component: 'c1'}
-        ]),
-        hosts: [{hostName: 'h1'}],
-        m: 'one host and one component',
-        e:{
-          blueprint: {
-            host_groups: [
-              {
-                name: 'host-group-1',
-                components: [
-                  { name: 'c1' }
-                ]
-              }
-            ]
-          },
-          blueprint_cluster_binding: {
-            host_groups: [
-              {
-                name: 'host-group-1',
-                hosts: [
-                  { fqdn: 'h1' }
-                ]
-              }
-            ]
-          }
-        }
-      },
-      {
-        masterComponentHosts: Em.A([
-          {hostName: 'h1', component: 'c1'},
-          {hostName: 'h2', component: 'c2'},
-          {hostName: 'h2', component: 'c3'}
-        ]),
-        hosts: [{hostName: 'h1'}, {hostName: 'h2'}, {hostName: 'h3'}],
-        m: 'multiple hosts and multiple components',
-        e: {
-          blueprint: {
-            host_groups: [
-              {
-                name: 'host-group-1',
-                components: [
-                  { name: 'c1' }
-                ]
-              },
-              {
-                name: 'host-group-2',
-                components: [
-                  { name: 'c2' },
-                  { name: 'c3' }
-                ]
-              },
-              {
-                name: 'host-group-3',
-                components: []
-              }
-            ]
-          },
-          blueprint_cluster_binding: {
-            host_groups: [
-              {
-                name: 'host-group-1',
-                hosts: [
-                  { fqdn: 'h1' }
-                ]
-              },
-              {
-                name: 'host-group-2',
-                hosts: [
-                  { fqdn: 'h2' }
-                ]
-              },
-              {
-                name: 'host-group-3',
-                hosts: [
-                  { fqdn: 'h3' }
-                ]
-              }
-            ]
-          }
-        }
-      }
-    ]);
-    tests.forEach(function (test) {
-      it(test.m, function () {
-        controller.set('content.masterComponentHosts', test.masterComponentHosts);
-        controller.set('hosts', test.hosts);
-        var r = controller.getCurrentMastersBlueprint();
-        expect(r).to.eql(test.e);
-      });
-    });
-  });
-
-  describe('#getCurrentBlueprint', function () {
-    var tests = Em.A([
-      {
-        clientComponents: Em.A([{component_name: "name1"}]),
-        hosts: Em.A([
-          Em.Object.create({
-            checkboxes: Em.A([
-              Em.Object.create({
-                component: 'c1',
-                checked: true
-              }),
-              Em.Object.create({
-                component: 'CLIENT',
-                checked: true
-              })
-            ])
-          })
-        ]),
-        m: 'one host and one component',
-        e:{
-          blueprint: {
-            host_groups: [
-              {
-                name: 'host-group-1',
-                components: [
-                  { name: 'c1' },
-                  { name: 'name1' }
-                ]
-              }
-            ]
-          },
-          blueprint_cluster_binding: {
-            host_groups: [
-              {
-                name: 'host-group-1',
-                hosts: [
-                  {}
-                ]
-              }
-            ]
-          }
-        }
-      }
-    ]);
-    tests.forEach(function (test) {
-      it(test.m, function () {
-        controller.set('content.clients', test.clientComponents);
-        controller.set('hosts', test.hosts);
-        var r = controller.getCurrentBlueprint();
-        expect(JSON.parse(JSON.stringify(r))).to.eql(JSON.parse(JSON.stringify(test.e)));
-      });
-    });
-  });
-
-  describe('#callServerSideValidation', function () {
-
-    var cases = [
-        {
-          controllerName: 'installerController',
-          hosts: [
-            {
-              hostName: 'h0'
-            },
-            {
-              hostName: 'h1'
-            }
-          ],
-          expected: [
-            ['c0', 'c6'],
-            ['c1', 'c3', 'c8']
-          ]
-        },
-        {
-          controllerName: 'addServiceController',
-          hosts: [
-            {
-              hostName: 'h0'
-            },
-            {
-              hostName: 'h1'
-            }
-          ],
-          expected: [
-            ['c0', 'c6'],
-            ['c1', 'c3', 'c8']
-          ]
-        },
-        {
-          controllerName: 'addHostController',
-          hosts: [
-            {
-              hostName: 'h0'
-            }
-          ],
-          expected: [
-            ['c0', 'c2', 'c5', 'c6'],
-            ['c1', 'c2', 'c3', 'c5', 'c8']
-          ]
-        }
-      ],
-      expectedHostGroups = [
-        {
-          name: 'host-group-1',
-          fqdn: 'h0'
-        },
-        {
-          name: 'host-group-2',
-          fqdn: 'h1'
-        }
-      ];
-
-    beforeEach(function () {
-      controller.get('content').setProperties({
-        selectedMpacks: [
-          {
-            name: "mpack",
-            version: "1"
-          }
-        ],
-        recommendations: {
-          blueprint: {
-            host_groups: [
-              {
-                components: [
-                  {
-                    name: 'c6'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                components: [
-                  {
-                    name: 'c8'
-                  }
-                ],
-                name: 'host-group-2'
-              }
-            ]
-          },
-          blueprint_cluster_binding: {
-            host_groups: [
-              {
-                hosts: [
-                  {
-                    fqdn: 'h0'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                hosts: [
-                  {
-                    fqdn: 'h1'
-                  }
-                ],
-                name: 'host-group-2'
-              }]
-          }
-        },
-        clients: [
-          {
-            component_name: 'c3'
-          }
-        ]
-      });
-      sinon.stub(App.StackService, 'find', function () {
-        return [
-          Em.Object.create({
-            serviceName: 's0',
-            isSelected: true
-          }),
-          Em.Object.create({
-            serviceName: 's1',
-            isInstalled: true,
-            isSelected: true
-          })
-        ];
-      });
-      sinon.stub(App.StackServiceComponent, 'find', function () {
-        return [
-          Em.Object.create({
-            componentName: 'c0',
-            isSlave: true
-          }),
-          Em.Object.create({
-            componentName: 'c1',
-            isSlave: true,
-            isShownOnInstallerSlaveClientPage: true
-          }),
-          Em.Object.create({
-            componentName: 'c2',
-            isSlave: true,
-            isShownOnInstallerSlaveClientPage: false
-          }),
-          Em.Object.create({
-            componentName: 'c3',
-            isClient: true
-          }),
-          Em.Object.create({
-            componentName: 'c4',
-            isClient: true,
-            isRequiredOnAllHosts: false
-          }),
-          Em.Object.create({
-            componentName: 'c5',
-            isClient: true,
-            isRequiredOnAllHosts: true
-          }),
-          Em.Object.create({
-            componentName: 'c6',
-            isMaster: true,
-            isShownOnInstallerAssignMasterPage: true
-          }),
-          Em.Object.create({
-            componentName: 'c7',
-            isMaster: true,
-            isShownOnInstallerAssignMasterPage: false
-          }),
-          Em.Object.create({
-            componentName: 'c8',
-            isMaster: true,
-            isShownOnAddServiceAssignMasterPage: true
-          }),
-          Em.Object.create({
-            componentName: 'c9',
-            isMaster: true,
-            isShownOnAddServiceAssignMasterPage: false
-          })
-        ];
-      });
-      sinon.stub(controller, 'getCurrentBlueprint', function () {
-        return {
-          blueprint: {
-            host_groups: [
-              {
-                components: [
-                  {
-                    name: 'c0'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                components: [
-                  {
-                    name: 'c1'
-                  },
-                  {
-                    name: 'c3'
-                  }
-                ],
-                name: 'host-group-2'
-              }
-            ]
-          },
-          blueprint_cluster_binding: {
-            host_groups: [
-              {
-                hosts: [
-                  {
-                    fqdn: 'h0'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                hosts: [
-                  {
-                    fqdn: 'h1'
-                  }
-                ],
-                name: 'host-group-2'
-              }]
-          }
-        };
-      });
-      sinon.stub(controller, 'getCurrentMastersBlueprint', function () {
-        return {
-          blueprint: {
-            host_groups: [
-              {
-                components: [
-                  {
-                    name: 'c6'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                components: [
-                  {
-                    name: 'c8'
-                  }
-                ],
-                name: 'host-group-2'
-              }
-            ]
-          },
-          blueprint_cluster_binding: {
-            host_groups: [
-              {
-                hosts: [
-                  {
-                    fqdn: 'h0'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                hosts: [
-                  {
-                    fqdn: 'h1'
-                  }
-                ],
-                name: 'host-group-2'
-              }]
-          }
-        };
-      });
-      sinon.stub(App, 'get').withArgs('components.clients').returns(['c3', 'c4']);
-      sinon.stub(controller, 'getCurrentMasterSlaveBlueprint', function () {
-        return {
-          blueprint: {
-            host_groups: [
-              {
-                components: [
-                  {
-                    name: 'c6'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                components: [
-                  {
-                    name: 'c8'
-                  }
-                ],
-                name: 'host-group-2'
-              }
-            ]
-          },
-          blueprint_cluster_binding: {
-            host_groups: [
-              {
-                hosts: [
-                  {
-                    fqdn: 'h0'
-                  }
-                ],
-                name: 'host-group-1'
-              },
-              {
-                hosts: [
-                  {
-                    fqdn: 'h1'
-                  }
-                ],
-                name: 'host-group-2'
-              }]
-          }
-        };
-      });
-      sinon.stub(App.Host, 'find', function () {
-        return [
-          {
-            hostName: 'h1'
-          }
-        ];
-      });
-    });
-
-    afterEach(function () {
-      App.StackService.find.restore();
-      App.StackServiceComponent.find.restore();
-      controller.getCurrentBlueprint.restore();
-      controller.getCurrentMastersBlueprint.restore();
-      App.get.restore();
-      controller.getCurrentMasterSlaveBlueprint.restore();
-      App.Host.find.restore();
-    });
-
-    cases.forEach(function (item) {
-      describe(item.controllerName, function () {
-
-        beforeEach(function () {
-          controller.set('hosts', item.hosts);
-          controller.set('content.controllerName', item.controllerName);
-          controller.callServerSideValidation();
-        });
-
-        it('blueprint.host_groups count is correct', function () {
-          expect(controller.get('content.recommendationsHostGroups.blueprint.host_groups.length')).to.equal(expectedHostGroups.length);
-        });
-
-        it('blueprint_cluster_binding.host_groups count is correct', function () {
-          expect(controller.get('content.recommendationsHostGroups.blueprint_cluster_binding.host_groups.length')).to.equal(expectedHostGroups.length);
-        });
-
-        item.expected.forEach(function (e, index) {
-          it('components are valid for group# ' + (index + 1), function () {
-            expect(controller.get('content.recommendationsHostGroups.blueprint.host_groups')[index].components.mapProperty('name').sort()).to.be.eql(e);
-          });
-        });
-
-        expectedHostGroups.forEach(function (group) {
-          it(group.name, function () {
-            var bpGroup = controller.get('content.recommendationsHostGroups.blueprint_cluster_binding.host_groups').findProperty('name', group.name);
-            expect(bpGroup.hosts).to.have.length(1);
-            expect(bpGroup.hosts[0].fqdn).to.equal(group.fqdn);
-          });
-        });
-
-      });
-    });
-
-  });
-
   describe('#isAllCheckboxesEmpty', function () {
 
     Em.A([
@@ -1699,7 +1045,6 @@ describe('App.WizardStep6Controller', function () {
 
     beforeEach(function () {
       sinon.stub(controller, 'render', Em.K);
-      sinon.stub(controller, 'callValidation', Em.K);
       sinon.stub(App.StackService, 'find').returns([
         Em.Object.create({
           isSelected: true,
@@ -1738,7 +1083,6 @@ describe('App.WizardStep6Controller', function () {
 
     afterEach(function () {
       controller.render.restore();
-      controller.callValidation.restore();
       App.StackService.find.restore();
     });
 
diff --git a/ambari-web/test/controllers/wizard/step8_test.js b/ambari-web/test/controllers/wizard/step8_test.js
index 6d3832d..1d2f9e1 100644
--- a/ambari-web/test/controllers/wizard/step8_test.js
+++ b/ambari-web/test/controllers/wizard/step8_test.js
@@ -104,7 +104,7 @@ var services = Em.A([
     serviceName: 's4',
     isSelected: true,
     isInstalled: false,
-    displayNameOnSelectServicePage: 's03',
+    displayNameOnSelectServicePage: 's04',
     isClientOnlyService: true,
     serviceComponents: Em.A([
       Em.Object.create({
@@ -337,28 +337,14 @@ describe('App.WizardStep8Controller', function () {
       installerStep8Controller.set('services', Em.A([]));
       installerStep8Controller.reopen({selectedServices: selectedServices});
       installerStep8Controller.loadServices();
+      console.log(installerStep8Controller.get('services'));
     });
 
     it('should load services', function () {
       var expected = [
         {
-          "service_name": "s1",
-          "display_name": "s01",
-          "service_components": []
-        },
-        {
-          "service_name": "s2",
-          "display_name": "s02",
-          "service_components": []
-        },
-        {
-          "service_name": "s3",
-          "display_name": "s03",
-          "service_components": []
-        },
-        {
           "service_name": "s4",
-          "display_name": "s03",
+          "display_name": "s04",
           "service_components": [
             {
               "component_name": "CLIENT",
@@ -1294,7 +1280,7 @@ describe('App.WizardStep8Controller', function () {
           componentName = 'c1';
         installerStep8Controller.registerHostsToComponent(hostNames, componentName);
         var data = JSON.parse(installerStep8Controller.addRequestToAjaxQueue.args[0][0].data.data);
-        expect(data.RequestInfo.query).to.equal('Hosts/host_name=h1|Hosts/host_name=h2');
+        expect(data.RequestInfo.query).to.equal('Hosts/host_name.in(h1,h2)');
         expect(data.Body.host_components[0].HostRoles.component_name).to.equal('c1');
       });
 
diff --git a/ambari-web/test/mixins/common/configs/configs_saver_test.js b/ambari-web/test/mixins/common/configs/configs_saver_test.js
index 1d8f9d7..22768af 100644
--- a/ambari-web/test/mixins/common/configs/configs_saver_test.js
+++ b/ambari-web/test/mixins/common/configs/configs_saver_test.js
@@ -138,6 +138,7 @@ describe('App.ConfigsSaverMixin', function() {
     it('generates config without properties', function() {
       expect(mixin.createDesiredConfig('type1')).to.eql({
         "Config": {
+          "tag": "v1",
           "type": 'type1',
           "properties": {},
           "service_config_version_note": ""
@@ -148,6 +149,7 @@ describe('App.ConfigsSaverMixin', function() {
     it('generates config with properties', function() {
       expect(mixin.createDesiredConfig('type1', [Em.Object.create({name: 'p1', value: 'v1', isRequiredByAgent: true}), Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent: true})], "note")).to.eql({
         "Config": {
+          "tag": "v1",
           "type": 'type1',
           "properties": {
             "p1": 'v1',
@@ -161,6 +163,7 @@ describe('App.ConfigsSaverMixin', function() {
     it('generates config with properties and skip isRequiredByAgent', function() {
       expect(mixin.createDesiredConfig('type1', [Em.Object.create({name: 'p1', value: 'v1', isRequiredByAgent: true}), Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent: false})], "note")).to.eql({
         "Config": {
+          "tag": "v1",
           "type": 'type1',
           "properties": {
             p1: 'v1'
@@ -173,6 +176,7 @@ describe('App.ConfigsSaverMixin', function() {
     it('generates config with properties and skip service_config_version_note', function() {
       expect(mixin.createDesiredConfig('type1', [Em.Object.create({name: 'p1', value: 'v1', isRequiredByAgent: true})], "note", true)).to.eql({
         "Config": {
+          "tag": "v1",
           "type": 'type1',
           "properties": {
             p1: 'v1'
@@ -192,6 +196,7 @@ describe('App.ConfigsSaverMixin', function() {
           Em.Object.create({name: 'p7', value: 'v7', isRequiredByAgent: true, propertyType: ["PASSWORD"]})
         ], "note")).to.eql({
           "Config": {
+            "tag": "v1",
             "type": 'type1',
             "properties": {
               p1: 'v1',
diff --git a/ambari-web/test/views/wizard/step6_view_test.js b/ambari-web/test/views/wizard/step6_view_test.js
index 4f349e8..4c722c0 100644
--- a/ambari-web/test/views/wizard/step6_view_test.js
+++ b/ambari-web/test/views/wizard/step6_view_test.js
@@ -116,7 +116,6 @@ describe('App.WizardStep6View', function() {
     var e;
     beforeEach(function() {
       sinon.stub(view.get('controller'), 'checkCallback', Em.K);
-      sinon.stub(view.get('controller'), 'callValidation', Em.K);
 
       e = {
         context: {
@@ -128,7 +127,6 @@ describe('App.WizardStep6View', function() {
     });
     afterEach(function() {
       view.get('controller').checkCallback.restore();
-      view.get('controller').callValidation.restore();
     });
 
     it("checked is false", function() {
@@ -138,10 +136,6 @@ describe('App.WizardStep6View', function() {
     it("checkCallback is called with correct data", function() {
       expect(view.get('controller').checkCallback.calledWith('c1')).to.be.true;
     });
-
-    it("callValidation is called once", function() {
-      expect(view.get('controller').callValidation.calledOnce).to.be.true;
-    });
   });
 
   describe("#columnCount", function() {

-- 
To stop receiving notification emails like this one, please contact
jgolieb@apache.org.