You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2013/11/26 12:20:40 UTC

git commit: AMBARI-3883 Provide config-groups capability in installer. (atkach)

Updated Branches:
  refs/heads/trunk 731618c40 -> 275096202


AMBARI-3883 Provide config-groups capability in installer. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/27509620
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/27509620
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/27509620

Branch: refs/heads/trunk
Commit: 275096202f7cad9862b1ff0ddbc37878ccbfdaa7
Parents: 731618c
Author: atkach <an...@gmail.com>
Authored: Tue Nov 26 13:20:23 2013 +0200
Committer: atkach <an...@gmail.com>
Committed: Tue Nov 26 13:20:23 2013 +0200

----------------------------------------------------------------------
 ambari-web/app/config.js                        |   2 +-
 ambari-web/app/controllers/installer.js         |  10 ++
 ambari-web/app/controllers/main/service/item.js |  16 ++-
 .../service/manage_config_groups_controller.js  | 132 +++++++++++++++++++
 ambari-web/app/controllers/wizard.js            |  47 ++++---
 .../app/controllers/wizard/step7_controller.js  | 120 +++++++++++++++++
 ambari-web/app/messages.js                      |   1 +
 ambari-web/app/models/service_config.js         |   1 +
 ambari-web/app/routes/installer.js              |   3 +
 ambari-web/app/styles/application.less          |   3 +
 .../templates/common/configs/service_config.hbs |   3 +
 ambari-web/app/utils/config.js                  |  46 +++----
 .../common/configs/overriddenProperty_view.js   |   1 -
 .../app/views/common/configs/services_config.js |  20 +--
 .../main/service/manage_config_groups_view.js   |   2 +-
 15 files changed, 352 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js
index ce0619f..2a09cdd 100644
--- a/ambari-web/app/config.js
+++ b/ambari-web/app/config.js
@@ -45,7 +45,7 @@ App.enableExperimental = false;
 App.supports = {
   addServices: false,
   hostOverrides: true,
-  hostOverridesInstaller: false,
+  hostOverridesInstaller: true,
   hostOverridesHost: true,
   mirroring: false,
   secureCluster: true,

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index dbb0923..f6cecde 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -34,6 +34,7 @@ App.InstallerController = App.WizardController.extend({
     masterComponentHosts: null,
     serviceConfigProperties: null,
     advancedServiceConfig: null,
+    configGroups: [],
     slaveGroupProperties: null,
     stacks: null,
     controllerName: 'installerController'
@@ -311,6 +312,14 @@ App.InstallerController = App.WizardController.extend({
 
     this.set('content.advancedServiceConfig', this.getDBProperty('advancedServiceConfig'));
   },
+  /**
+   * Load config groups from local DB
+   */
+  loadServiceConfigGroups: function () {
+    var serviceConfigGroups = this.getDBProperty('serviceConfigGroups') || [];
+    this.set('content.configGroups', serviceConfigGroups);
+    console.log("InstallerController.configGroups: loaded config ", serviceConfigGroups);
+  },
 
   /**
    * Load information about hosts with clients components
@@ -442,6 +451,7 @@ App.InstallerController = App.WizardController.extend({
       case '9':
       case '8':
       case '7':
+        this.loadServiceConfigGroups();
         this.loadServiceConfigProperties();
       case '6':
         this.loadSlaveComponentHosts();

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/controllers/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js
index b7986cb..76778ed 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -227,19 +227,27 @@ App.MainServiceItemController = Em.Controller.extend({
     App.router.transitionTo('reassign');
   },
 
-  manageConfigurationGroups: function () {
-    var serviceName = this.get('content.serviceName');
-    var displayName = this.get('content.displayName');
+  manageConfigurationGroups: function (controller) {
+    var serviceData = (controller && controller.get('selectedService')) || this.get('content');
+    var serviceName = serviceData.get('serviceName');
+    var displayName = serviceData.get('displayName');
     App.ModalPopup.show({
       header: Em.I18n.t('services.service.config_groups_popup.header').format(displayName),
       bodyClass: App.MainServiceManageConfigGroupView.extend({
         serviceName: serviceName,
-        controllerBinding: 'App.router.manageConfigGroupsController'
+        allConfigGroupsNames: (controller && controller.get('allConfigGroupsNames')),
+        controllerBinding: (!!controller) ? 'App.router.installerManageConfigGroupsController' : 'App.router.manageConfigGroupsController'
       }),
       classNames: ['sixty-percent-width-modal', 'manage-configuration-group-popup'],
       primary: Em.I18n.t('common.save'),
       onPrimary: function() {
         // Save modified config-groups
+        if (!!controller) {
+          controller.set('selectedService.configGroups', App.router.get('installerManageConfigGroupsController.configGroups'));
+          controller.selectedServiceObserver();
+          this.hide();
+          return;
+        }
         var modifiedConfigGroups = this.get('subViewController.hostsModifiedConfigGroups');
         console.log("manageConfigurationGroups(): Saving modified config-groups: ", modifiedConfigGroups);
         var self = this;

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
index 836ae35..423e975 100644
--- a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
+++ b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
@@ -458,3 +458,135 @@ App.ManageConfigGroupsController = Em.Controller.extend({
     return !!(modifiedGroups.toClearHosts.length || modifiedGroups.toSetHosts.length);
   }.property('hostsModifiedConfigGroups', 'hostsModifiedConfigGroups.length')
 });
+
+
+App.InstallerManageConfigGroupsController = App.ManageConfigGroupsController.extend({
+  name: 'installerManageConfigGroupsController',
+
+  loadConfigGroups: function (serviceName, allConfigGroupsNames) {
+    this.set('serviceName', serviceName);
+    this.set('allConfigGroupsNames', allConfigGroupsNames);
+    var loadedHostsToGroupMap = this.get('loadedHostsToGroupMap');
+    var configGroups = this.copyConfigGroups(App.router.get('wizardStep7Controller.selectedService.configGroups'));
+    configGroups.forEach(function (configGroup) {
+      if (!configGroup.get('isDefault')) {
+        loadedHostsToGroupMap[configGroup.name] = configGroup.hosts.slice();
+      }
+    });
+    this.set('configGroups', configGroups);
+    this.set('isLoaded', true);
+  },
+  /**
+   * copy config groups to manage popup to give user choice whether or not save changes
+   * @param originGroups
+   * @return {Array}
+   */
+  copyConfigGroups: function (originGroups) {
+    var configGroups = [];
+    var defaultConfigGroup = App.ConfigGroup.create(originGroups.findProperty('isDefault'));
+    originGroups.forEach(function (configGroup) {
+      if (!configGroup.get('isDefault')) {
+        var copiedGroup = App.ConfigGroup.create($.extend(true, {}, configGroup));
+        copiedGroup.set('parentConfigGroup', defaultConfigGroup);
+        configGroups.pushObject(copiedGroup);
+      }
+    });
+    defaultConfigGroup.set('childConfigGroups', configGroups.slice());
+    configGroups.pushObject(defaultConfigGroup);
+    return configGroups;
+  },
+  /**
+   * delete selected config group
+   */
+  deleteConfigGroup: function () {
+    var selectedConfigGroup = this.get('selectedConfigGroup');
+    if (this.get('isDeleteGroupDisabled')) {
+      return;
+    }
+    //move hosts of group to default group (available hosts)
+    this.set('selectedHosts', selectedConfigGroup.get('hosts'));
+    this.deleteHosts();
+    this.get('configGroups').removeObject(selectedConfigGroup);
+    delete this.get('loadedHostsToGroupMap')[selectedConfigGroup.get('name')];
+    this.set('selectedConfigGroup', this.get('configGroups').findProperty('isDefault'));
+  },
+  /**
+   * rename new config group
+   */
+  renameConfigGroup: function () {
+    if(this.get('selectedConfigGroup.name') == "Default") {
+      return;
+    }
+    var self = this;
+    App.ModalPopup.show({
+      primary: Em.I18n.t('ok'),
+      secondary: Em.I18n.t('common.cancel'),
+      header: Em.I18n.t('services.service.config_groups.rename_config_group_popup.header'),
+      bodyClass: Ember.View.extend({
+        templateName: require('templates/main/service/new_config_group')
+      }),
+      configGroupName: self.get('selectedConfigGroup.name'),
+      configGroupDesc: self.get('selectedConfigGroup.description'),
+      warningMessage: '',
+      vaildate: function () {
+        var warningMessage = '';
+        if (self.get('allConfigGroupsNames').contains(this.get('configGroupName'))) {
+          warningMessage = Em.I18n.t("config.group.selection.dialog.err.name.exists");
+        }
+        this.set('warningMessage', warningMessage);
+      }.observes('configGroupName'),
+      enablePrimary: function () {
+        return this.get('configGroupName').length > 0 && !this.get('warningMessage');
+      }.property('warningMessage', 'configGroupName'),
+      onPrimary: function () {
+        self.set('selectedConfigGroup.name', this.get('configGroupName'));
+        self.set('selectedConfigGroup.description', this.get('configGroupDesc'));
+        this.hide();
+      }
+    });
+  },
+  /**
+   * add new config group
+   */
+  addConfigGroup: function () {
+    var self = this;
+    this.addGroupPopup = App.ModalPopup.show({
+      primary: Em.I18n.t('ok'),
+      secondary: Em.I18n.t('common.cancel'),
+      header: Em.I18n.t('services.service.config_groups.add_config_group_popup.header'),
+      bodyClass: Ember.View.extend({
+        templateName: require('templates/main/service/new_config_group')
+      }),
+      configGroupName: "",
+      configGroupDesc: "",
+      warningMessage: '',
+      vaildate: function () {
+        var warningMessage = '';
+        if (self.get('allConfigGroupsNames').contains(this.get('configGroupName'))) {
+          warningMessage = Em.I18n.t("config.group.selection.dialog.err.name.exists");
+        }
+        this.set('warningMessage', warningMessage);
+      }.observes('configGroupName'),
+      enablePrimary: function () {
+        return this.get('configGroupName').length > 0 && !this.get('warningMessage');
+      }.property('warningMessage', 'configGroupName'),
+      onPrimary: function () {
+        var defaultConfigGroup = self.get('configGroups').findProperty('isDefault');
+        var newConfigGroupData = App.ConfigGroup.create({
+          id: null,
+          name: this.get('configGroupName'),
+          description: this.get('configGroupDesc'),
+          isDefault: false,
+          parentConfigGroup: defaultConfigGroup,
+          service: Em.Object.create({id: self.get('serviceName')}),
+          hosts: [],
+          configSiteTags: []
+        });
+        self.get('loadedHostsToGroupMap')[newConfigGroupData.get('name')] = [];
+        self.get('configGroups').pushObject(newConfigGroupData);
+        defaultConfigGroup.get('childConfigGroups').pushObject(newConfigGroupData);
+        this.hide();
+      }
+    });
+  }
+})

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index 48c1cb0..63a17c1 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -712,21 +712,6 @@ App.WizardController = Em.Controller.extend({
       }
 
       _content.get('configs').forEach(function (_configProperties) {
-        var overrides = _configProperties.get('overrides');
-        var overridesArray = [];
-        if (overrides != null) {
-          overrides.forEach(function (override) {
-            var overrideEntry = {
-              value: override.get('value'),
-              hosts: []
-            };
-            override.get('selectedHostOptions').forEach(function (host) {
-              overrideEntry.hosts.push(host);
-            });
-            overridesArray.push(overrideEntry);
-          });
-        }
-        overridesArray = (overridesArray.length) ? overridesArray : null;
         var configProperty = {
           id: _configProperties.get('id'),
           name: _configProperties.get('name'),
@@ -736,13 +721,41 @@ App.WizardController = Em.Controller.extend({
           serviceName: _configProperties.get('serviceName'),
           domain: _configProperties.get('domain'),
           filename: _configProperties.get('filename'),
-          displayType: _configProperties.get('displayType'),
-          overrides: overridesArray
+          displayType: _configProperties.get('displayType')
         };
         serviceConfigProperties.push(configProperty);
       }, this);
     }, this);
     this.setDBProperty('serviceConfigProperties', serviceConfigProperties);
     this.set('content.serviceConfigProperties', serviceConfigProperties);
+  },
+  /**
+   * save Config groups
+   * @param stepController
+   */
+  saveServiceConfigGroups: function (stepController) {
+    var serviceConfigGroups = [];
+    stepController.get('stepConfigs').forEach(function (service) {
+      service.get('configGroups').forEach(function (configGroup) {
+        var properties = [];
+        configGroup.get('properties').forEach(function (property) {
+          properties.push({
+            name: property.get('name'),
+            value: property.get('value')
+          })
+        });
+        //configGroup copied into plain JS object to avoid Converting circular structure to JSON
+        serviceConfigGroups.push({
+          name: configGroup.get('name'),
+          description: configGroup.get('description'),
+          hosts: configGroup.get('hosts'),
+          properties: properties,
+          isDefault: configGroup.get('isDefault'),
+          service: {id: configGroup.get('service.id')}
+        });
+      }, this)
+    }, this);
+    this.setDBProperty('serviceConfigGroups', serviceConfigGroups);
+    this.set('content.serviceConfigProperties', serviceConfigGroups);
   }
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/controllers/wizard/step7_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js
index a0b5252..f1f1f8f 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -46,6 +46,20 @@ App.WizardStep7Controller = Em.Controller.extend({
 
   gangliaMoutDir:'/',
 
+  overrideToAdd: null,
+
+  isInstaller: true,
+
+  configGroups: [],
+  selectedConfigGroup: null,
+  allConfigGroupsNames: function () {
+    var names = [];
+    this.get('stepConfigs').forEach(function (service) {
+      names.pushObjects(service.get('configGroups').mapProperty('name'));
+    });
+    return names.uniq();
+  }.property('selectedService.configGroups.@each.name'),
+
   isSubmitDisabled: function () {
     return (!this.stepConfigs.filterProperty('showConfig', true).everyProperty('errorCount', 0) || this.get("miscModalVisible"));
   }.property('stepConfigs.@each.errorCount', 'miscModalVisible'),
@@ -108,6 +122,9 @@ App.WizardStep7Controller = Em.Controller.extend({
     }
 
     this.set('stepConfigs', serviceConfigs);
+    if (App.supports.hostOverridesInstaller) {
+      this.loadConfigGroups(this.get('content.configGroups'));
+    }
     this.activateSpecialConfigs();
     this.set('selectedService', this.get('stepConfigs').filterProperty('showConfig', true).objectAt(0));
 
@@ -116,6 +133,109 @@ App.WizardStep7Controller = Em.Controller.extend({
     }
   },
 
+  selectedServiceObserver: function () {
+    if (App.supports.hostOverridesInstaller && this.get('selectedService') && (this.get('selectedService.serviceName') !== 'MISC')) {
+      var serviceGroups = this.get('selectedService.configGroups');
+      this.set('configGroups', serviceGroups);
+      this.set('selectedConfigGroup', serviceGroups.findProperty('isDefault'));
+    }
+  }.observes('selectedService.configGroups.@each'),
+  /**
+   * load default groups for each service in case of initial load
+   * @param serviceConfigGroups
+   */
+  loadConfigGroups: function (serviceConfigGroups) {
+    var services = this.get('stepConfigs');
+    var hosts = this.get('getAllHosts').mapProperty('hostName');
+    services.forEach(function (service) {
+      if (service.get('serviceName') === 'MISC') return;
+      var serviceRawGroups = serviceConfigGroups.filterProperty('service.id', service.serviceName);
+      if (!serviceRawGroups.length) {
+        service.set('configGroups', [
+          App.ConfigGroup.create({
+            name: "Default",
+            description: "Default cluster level " + service.serviceName + " configuration",
+            isDefault: true,
+            hosts: hosts,
+            service: Em.Object.create({
+              id: service.serviceName
+            })
+          })
+        ]);
+      } else {
+        var defaultGroup = App.ConfigGroup.create(serviceRawGroups.findProperty('isDefault'));
+        var serviceGroups = service.get('configGroups');
+        serviceRawGroups.filterProperty('isDefault', false).forEach(function (configGroup) {
+          var readyGroup = App.ConfigGroup.create(configGroup);
+          var wrappedProperties = [];
+          readyGroup.get('properties').forEach(function(property){
+            wrappedProperties.pushObject(App.ServiceConfigProperty.create(property));
+          });
+          wrappedProperties.setEach('group', readyGroup);
+          readyGroup.set('properties', wrappedProperties);
+          readyGroup.set('parentConfigGroup', defaultGroup);
+          serviceGroups.pushObject(readyGroup);
+        });
+        defaultGroup.set('childConfigGroups', serviceGroups);
+        serviceGroups.pushObject(defaultGroup);
+      }
+    });
+  },
+
+  selectConfigGroup: function (event) {
+    this.set('selectedConfigGroup', event.context);
+  },
+
+  /**
+   * rebuild list of configs switch of config group:
+   * on default - display all configs from default group and configs from non-default groups as disabled
+   * on non-default - display all from default group as disabled and configs from selected non-default group
+   */
+  switchConfigGroupConfigs: function () {
+    var serviceConfigs = this.get('selectedService.configs');
+    var selectedGroup = this.get('selectedConfigGroup');
+    var overrideToAdd = this.get('overrideToAdd');
+    var displayedConfigGroups = (selectedGroup.get('isDefault')) ?
+        this.get('selectedService.configGroups').filterProperty('isDefault', false) :
+        [this.get('selectedConfigGroup')];
+    var overrides = [];
+
+    displayedConfigGroups.forEach(function (group) {
+      overrides.pushObjects(group.get('properties'));
+    });
+    serviceConfigs.forEach(function (config) {
+      var configOverrides = overrides.filterProperty('name', config.get('name'));
+      config.set('isEditable', selectedGroup.get('isDefault'));
+      if (overrideToAdd && overrideToAdd.get('name') === config.get('name')) {
+        configOverrides.push(this.addOverrideProperty(config));
+        this.set('overrideToAdd', null);
+      }
+      configOverrides.setEach('isEditable', !selectedGroup.get('isDefault'));
+      config.set('overrides', configOverrides);
+    }, this);
+  }.observes('selectedConfigGroup'),
+  /**
+   * create overriden property and push it into Config group
+   * @param serviceConfigProperty
+   * @return {*}
+   */
+  addOverrideProperty: function (serviceConfigProperty) {
+    var overrides = serviceConfigProperty.get('overrides') || [];
+    var newSCP = App.ServiceConfigProperty.create(serviceConfigProperty);
+    var group = this.get('selectedService.configGroups').findProperty('name', this.get('selectedConfigGroup.name'));
+    newSCP.set('group', group);
+    newSCP.set('value', '');
+    newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
+    newSCP.set('parentSCP', serviceConfigProperty);
+    newSCP.set('isEditable', true);
+    group.get('properties').pushObject(newSCP);
+    overrides.pushObject(newSCP);
+    return newSCP;
+  },
+
+  manageConfigurationGroup: function () {
+    App.router.get('mainServiceItemController').manageConfigurationGroups(this);
+  },
    /**
    * make some configs visible depending on active services
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index cdd41e8..13c0c9f 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -963,6 +963,7 @@ Em.I18n.translations = {
   'services.service.actions.reassign.master':'Reassign {0}',
   'services.service.actions.reassign.master.hive':'Reassign HiveServer2, WebHCat Server, MySQL Server',
   'services.service.actions.manage_configuration_groups':'Manage Configuration Groups...',
+  'services.service.actions.manage_configuration_groups.short':'Manage Config Groups',
   'services.service.actions.serviceActions':'Service Actions',
   'services.service.summary.unknown':'unknown',
   'services.service.summary.notRunning':'Not Running',

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/models/service_config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service_config.js b/ambari-web/app/models/service_config.js
index 6d0b7bd..c00ac67 100644
--- a/ambari-web/app/models/service_config.js
+++ b/ambari-web/app/models/service_config.js
@@ -26,6 +26,7 @@ App.ServiceConfig = Ember.Object.extend({
   restartRequired: false,
   restartRequiredMessage: '',
   restartRequiredHostsAndComponents: {},
+  configGroups: [],
   errorCount: function () {
     var overrideErrors = 0;
     this.get('configs').filterProperty("overrides").forEach(function (e) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/routes/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js
index bf00c44..5de1864 100644
--- a/ambari-web/app/routes/installer.js
+++ b/ambari-web/app/routes/installer.js
@@ -309,6 +309,9 @@ module.exports = Em.Route.extend({
       var installerController = router.get('installerController');
       var wizardStep7Controller = router.get('wizardStep7Controller');
       installerController.saveServiceConfigProperties(wizardStep7Controller);
+      if (App.supports.hostOverridesInstaller) {
+        installerController.saveServiceConfigGroups(wizardStep7Controller);
+      }
       router.transitionTo('step8');
     }
   }),

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 6f3f49c..c7070f3 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -4236,6 +4236,9 @@ ul.inline li {
     width: auto;
     background: url(/img/spinner.gif) no-repeat;
   }
+  .link {
+    padding: 0 15px;
+  }
 }
 
 /*

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/templates/common/configs/service_config.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config.hbs b/ambari-web/app/templates/common/configs/service_config.hbs
index 246f44d..718afb0 100644
--- a/ambari-web/app/templates/common/configs/service_config.hbs
+++ b/ambari-web/app/templates/common/configs/service_config.hbs
@@ -67,6 +67,9 @@
     {{#if controller.isHostsConfigsPage}}
       &nbsp;<a href="#" {{action "switchHostGroup" target="controller"}}>{{t common.change}}</a>
     {{/if}}
+    {{#if controller.isInstaller}}
+        <a href="#" class="link" {{action "manageConfigurationGroup" target="controller"}}>{{t services.service.actions.manage_configuration_groups.short}}</a>
+    {{/if}}
      <div class="pull-right">
        {{view App.FilterComboboxView filterBinding="view.filter" columnsBinding="view.columns" }}
      </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 80d00af..5f9e520 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -587,7 +587,8 @@ App.config = Em.Object.create({
       serviceName: preDefinedServiceConfig.serviceName,
       displayName: preDefinedServiceConfig.displayName,
       configCategories: preDefinedServiceConfig.configCategories,
-      configs: []
+      configs: [],
+      configGroups: []
     });
     serviceConfig.configCategories.filterProperty('isCustomView', true).forEach(function (category) {
       switch (category.name) {
@@ -983,7 +984,7 @@ App.config = Em.Object.create({
    * @param callback  Callback function which is invoked when dialog
    *  is closed, cancelled or OK is pressed.
    */
-  launchConfigGroupSelectionCreationDialog : function(serviceId, configGroups, allConfigGroupsNames, configProperty, callback) {
+  launchConfigGroupSelectionCreationDialog : function(serviceId, configGroups, allConfigGroupsNames, configProperty, callback, isInstaller) {
     var self = this;
     var availableConfigGroups = configGroups.slice();
     // delete Config Groups, that already have selected property overridden
@@ -1023,8 +1024,9 @@ App.config = Em.Object.create({
           callback(selectedConfigGroup);
         } else {
           var newConfigGroupName = this.get('newConfigGroupName');
-          var newConfigGroup = self.createNewConfigurationGroup(serviceId, newConfigGroupName);
+          var newConfigGroup = self.createNewConfigurationGroup(serviceId, newConfigGroupName, isInstaller);
           if (newConfigGroup) {
+            newConfigGroup.set('parentConfigGroup', configGroups.findProperty('isDefault'));
             configGroups.pushObject(newConfigGroup);
             this.hide();
             callback(newConfigGroup);
@@ -1133,41 +1135,41 @@ App.config = Em.Object.create({
    * @return  Returns the created config-group or error as
    *        { configGroup: {id:4}, error: {...}}
    */
-  createNewConfigurationGroup: function (serviceId, configGroupName) {
-    var newConfigGroupData = null;
-    var description = "New configuration group created on " + new Date().toDateString();
+  createNewConfigurationGroup: function (serviceId, configGroupName, isInstaller) {
+    var newConfigGroupData = App.ConfigGroup.create({
+      id: null,
+      name: configGroupName,
+      description: "New configuration group created on " + new Date().toDateString(),
+      isDefault: false,
+      parentConfigGroup: null,
+      service: App.Service.find().findProperty('serviceName', serviceId),
+      hosts: [],
+      configSiteTags: [],
+      properties: []
+    });
+    if (isInstaller) {
+      newConfigGroupData.set('service', Em.Object.create({id: serviceId}));
+      return newConfigGroupData;
+    }
     var sendData = {
       name: 'config_groups.create',
       data: {
         'group_name': configGroupName,
         'service_id': serviceId,
-        'description': description
+        'description': newConfigGroupData.description
       },
       success: 'successFunction',
       error: 'errorFunction',
       successFunction: function (response) {
-        newConfigGroupData = App.ConfigGroup.create({
-          id: response.resources[0].ConfigGroup.id,
-          name: null,
-          description: null,
-          isDefault: false,
-          parentConfigGroup: null,
-          service: null,
-          hosts: [],
-          configSiteTags: []
-        });
+        newConfigGroupData.id = response.resources[0].ConfigGroup.id;
       },
       errorFunction: function () {
+        newConfigGroupData = null;
         console.error('Error in creating new Config Group');
       }
     };
     sendData.sender = sendData;
     App.ajax.send(sendData);
-    if (newConfigGroupData) {
-      newConfigGroupData.set('service', App.Service.find().findProperty('serviceName', serviceId));
-      newConfigGroupData.set('name', configGroupName);
-      newConfigGroupData.set('description', description);
-    }
     return newConfigGroupData;
   },
   

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/views/common/configs/overriddenProperty_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/overriddenProperty_view.js b/ambari-web/app/views/common/configs/overriddenProperty_view.js
index c772033..298d32c 100644
--- a/ambari-web/app/views/common/configs/overriddenProperty_view.js
+++ b/ambari-web/app/views/common/configs/overriddenProperty_view.js
@@ -20,7 +20,6 @@ var App = require('app');
 
 App.ServiceConfigView.SCPOverriddenRowsView = Ember.View.extend({
   templateName: require('templates/common/configs/overriddenProperty'),
-  controllerBinding: 'App.router.mainServiceInfoConfigsController',
   serviceConfigProperty: null, // is passed dynamically at runtime where ever
   // we are declaring this from configs.hbs ( we are initializing this from UI )
   categoryConfigs: null, // just declared as viewClass need it

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/views/common/configs/services_config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/services_config.js b/ambari-web/app/views/common/configs/services_config.js
index f5d0fa7..47b4962 100644
--- a/ambari-web/app/views/common/configs/services_config.js
+++ b/ambari-web/app/views/common/configs/services_config.js
@@ -38,7 +38,7 @@ App.ServiceConfigView = Em.View.extend({
   supportsHostOverrides: function () {
     switch (this.get('controller.name')) {
       case 'wizardStep7Controller':
-        return App.supports.hostOverridesInstaller;
+        return App.supports.hostOverridesInstaller && (this.get('controller.selectedService.serviceName') !== 'MISC');
       case 'mainServiceInfoConfigsController':
         return App.supports.hostOverrides;
       case 'mainHostServiceConfigsController':
@@ -46,7 +46,7 @@ App.ServiceConfigView = Em.View.extend({
       default:
         return false;
     }
-  }.property('controller.name'),
+  }.property('controller.name', 'controller.selectedService'),
   toggleRestartMessageView: function () {
     this.$('.service-body').toggle('blind', 200);
     this.set('isRestartMessageCollapsed', !this.get('isRestartMessageCollapsed'));
@@ -509,16 +509,18 @@ App.ServiceConfigsByCategoryView = Ember.View.extend({
     var serviceConfigProperty = event.contexts[0];
     var serviceConfigController = this.get('controller');
     var selectedConfigGroup = serviceConfigController.get('selectedConfigGroup');
+    var isInstaller = (this.get('controller.name') === 'wizardStep7Controller');
+    var configGroups = (isInstaller) ? serviceConfigController.get('selectedService.configGroups') : serviceConfigController.get('configGroups');
     if (selectedConfigGroup.get('isDefault')) {
       // Launch dialog to pick/create Config-group
       App.config.launchConfigGroupSelectionCreationDialog(this.get('service.serviceName'),
-          serviceConfigController.get('configGroups'), serviceConfigController.get('allConfigGroupsNames'), serviceConfigProperty, function (selectedGroupInPopup) {
-            console.log("launchConfigGroupSelectionCreationDialog(): Selected/Created:", selectedGroupInPopup);
-            if (selectedGroupInPopup) {
-              serviceConfigController.set('overrideToAdd', serviceConfigProperty);
-              serviceConfigController.set('selectedConfigGroup', selectedGroupInPopup);
-            }
-          });
+        configGroups, serviceConfigController.get('allConfigGroupsNames'), serviceConfigProperty, function (selectedGroupInPopup) {
+          console.log("launchConfigGroupSelectionCreationDialog(): Selected/Created:", selectedGroupInPopup);
+          if (selectedGroupInPopup) {
+            serviceConfigController.set('overrideToAdd', serviceConfigProperty);
+            serviceConfigController.set('selectedConfigGroup', selectedGroupInPopup);
+          }
+        }, isInstaller);
     } else {
       serviceConfigController.addOverrideProperty(serviceConfigProperty);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/27509620/ambari-web/app/views/main/service/manage_config_groups_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/manage_config_groups_view.js b/ambari-web/app/views/main/service/manage_config_groups_view.js
index c6f4577..9ba4a0f 100644
--- a/ambari-web/app/views/main/service/manage_config_groups_view.js
+++ b/ambari-web/app/views/main/service/manage_config_groups_view.js
@@ -59,7 +59,7 @@ App.MainServiceManageConfigGroupView = Em.View.extend({
   }.observes('controller.isLoaded', 'controller.configGroups'),
 
   didInsertElement: function () {
-    this.get('controller').loadConfigGroups(this.get('serviceName'));
+    this.get('controller').loadConfigGroups(this.get('serviceName'), this.get('allConfigGroupsNames'));
     $('.properties-link').tooltip();
     $("[rel='button-info']").tooltip();
   },