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

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

commit 6601a44ee9f789c55365bc83940bef9ece07c56f
Author: Jason Golieb <[email protected]>
AuthorDate: Thu Mar 29 16:00:26 2018 -0400

    Use new os/repo API in installer.
---
 ambari-web/app/controllers/installer.js            | 125 +---------
 .../wizard/customProductRepos_controller.js        | 269 ++++++++++++---------
 .../wizard/downloadMpacks_controller.js            |  30 +--
 ambari-web/app/messages.js                         |  84 +------
 ambari-web/app/routes/installer.js                 |   7 +-
 ambari-web/app/utils/ajax/ajax.js                  |  79 +++---
 ambari-web/app/views/main/dashboard/widgets.js     |  55 +++--
 7 files changed, 260 insertions(+), 389 deletions(-)

diff --git a/ambari-web/app/controllers/installer.js 
b/ambari-web/app/controllers/installer.js
index f176138..15a1f82 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -221,49 +221,6 @@ App.InstallerController = 
App.WizardController.extend(App.Persist, {
   },
 
   /**
-   * Load data for stacks from selected mpacks. This just tells the server to 
populate the version_definitions endpoint for the mpack that was registered.
-   *
-   * @param  {string} stackName
-   * @param  {string} stackVersion
-   * @param  {string} serviceName
-   */
-  createMpackStackVersion: function (stackName, stackVersion) {
-    return App.ajax.send({
-      name: 'mpack.create_version_definition',
-      sender: this,
-      data: {
-        name: stackName,
-        version: stackVersion
-      }
-    })
-  },
-
-  /**
-   * Loads stack version data (including supported OSes and repos) from the 
version_definitions endpoint
-   */
-  getMpackStackVersions: function () {
-    return App.ajax.send({
-      name: 'mpack.get_version_definitions',
-      sender: this
-    })
-  },
-
-  loadMpackStackInfoSuccess: function (versionDefinition) {
-    App.stackMapper.map(versionDefinition);
-  },
-
-  loadMpackStackInfoError: function(request, status, error) {
-    const message = Em.I18n.t('installer.error.mpackStackInfo');
-
-    App.showAlertPopup(
-      Em.I18n.t('common.error'), //header
-      message //body
-    );
-
-    console.log(`${message} ${status} - ${error}`);
-  },
-
-  /**
    * Load data for services selected from mpacks. Will be used at 
<code>Download Mpacks</code> step submit action.
    *
    * @param  {string} stackName
@@ -926,59 +883,6 @@ App.InstallerController = 
App.WizardController.extend(App.Persist, {
     App.showAlertPopup(header, body);
   },
 
-  updateRepoOSInfo: function (repoToUpdate, repo) {
-    var deferred = $.Deferred();
-    var repoVersion = this.prepareRepoForSaving(repo);
-    App.ajax.send({
-      name: 'admin.stack_versions.edit.repo',
-      sender: this,
-      data: {
-        stackName: repoToUpdate.stackName,
-        stackVersion: repoToUpdate.stackVersion,
-        repoVersionId: repoToUpdate.id,
-        repoVersion: repoVersion
-      }
-    }).success(function() {
-      deferred.resolve([]);
-    }).error(function() {
-      deferred.resolve([]);
-    });
-    return deferred.promise();
-  },
-
-  /**
-   * transform repo data into json for
-   * saving changes to repository version
-   * @param {Em.Object} repo
-   * @returns {{operating_systems: Array}}
-   */
-  prepareRepoForSaving: function(repo) {
-    var repoVersion = { "operating_systems": [] };
-    var ambariManagedRepositories = !repo.get('useRedhatSatellite');
-    repo.get('operatingSystems').forEach(function (os, k) {
-      repoVersion.operating_systems.push({
-        "OperatingSystems": {
-          "os_type": os.get("osType"),
-          "ambari_managed_repositories": ambariManagedRepositories
-        },
-        "repositories": []
-      });
-      os.get('repositories').forEach(function (repository) {
-        repoVersion.operating_systems[k].repositories.push({
-          "Repositories": {
-            "public_url": repository.get('baseUrlInit'),
-            "base_url": repository.get('baseUrl'),
-            "repo_id": repository.get('repoId'),
-            "repo_name": repository.get('repoName'),
-            "unique": repository.get('unique'),
-            "tags": repository.get('tags'),
-          }
-        })
-      })
-    });
-    return repoVersion;
-  },
-
   /**
    * Check validation of the customized local urls
    */
@@ -1116,7 +1020,7 @@ App.InstallerController = 
App.WizardController.extend(App.Persist, {
       {
         type: 'async',
         callback: function () {
-          return 
this.finishRegisteringMpacks(this.getStepSavedState('customProductRepos'));
+          return 
this.loadSelectedServiceInfo(this.getStepSavedState('customProductRepos'));
         }
       },
     ],
@@ -1499,28 +1403,18 @@ App.InstallerController = 
App.WizardController.extend(App.Persist, {
   },
 
   /**
-   * This runs when the step after Download Mpacks loads and completes the 
mpack registration process that was begun in the Download Mpacks step.
-   * It populates the StackService model from the stack version definitions.
-   * Then, it persists info about the selected services and the selected stack.
+   * Populates the StackService model from the "stack" info that was created 
when mpacks were registered in the Download Mpack step.
+   * Then, it locally persists info about the selected services.
    *
    * @param {Boolean} keepStackServices If true, previously loaded stack 
services are retained.
    *                                    This is to support back/forward 
navigation in the wizard
    *                                    and should correspond to the saved 
state of the step after Download Mpacks.
    * @return {object} a promise
    */
-  finishRegisteringMpacks: function (keepStackServices) {
+  loadSelectedServiceInfo: function (keepStackServices) {
     var dfd = $.Deferred();
 
-    this.getMpackStackVersions()
-    .fail(errors => {
-      this.addErrors(errors);
-      dfd.reject();
-    })
-    .always(data => {
-      data.items.forEach(versionDefinition => 
App.stackMapper.map(versionDefinition));
-      return this.clearStackServices(!keepStackServices);
-    })
-    .then(() => {
+    this.clearStackServices(!keepStackServices).then(() => {
       //get info about services from specific stack versions and save to 
StackService model
       const selectedServices = this.get('content.selectedServices');
       const servicePromises = selectedServices.map(service =>
@@ -1529,8 +1423,7 @@ App.InstallerController = 
App.WizardController.extend(App.Persist, {
       );
 
       return $.when(...servicePromises);
-    })
-    .then(() => {
+    }).then(() => {
       const services = App.StackService.find();
       this.set('content.services', services);
 
@@ -1548,12 +1441,6 @@ App.InstallerController = 
App.WizardController.extend(App.Persist, {
       this.set('content.clients', clients);
       this.save('clients');
 
-      //TODO: mpacks - hard coding this to use the name and version of the 
first stack/mpack for now. We need to get rid of the concept of "selected 
stack".
-      const stacks = App.Stack.find();
-      const selectedStack = stacks.objectAtContent(0);
-      this.set('content.selectedStack', { name: 
selectedStack.get('stackName'), version: selectedStack.get('stackVersion') });
-      this.save('selectedStack');
-
       dfd.resolve();
     });
     
diff --git a/ambari-web/app/controllers/wizard/customProductRepos_controller.js 
b/ambari-web/app/controllers/wizard/customProductRepos_controller.js
index 3bb1385..0a8cc9d 100644
--- a/ambari-web/app/controllers/wizard/customProductRepos_controller.js
+++ b/ambari-web/app/controllers/wizard/customProductRepos_controller.js
@@ -24,8 +24,6 @@ App.WizardCustomProductReposController = 
App.WizardStepController.extend({
 
   stepName: 'customProductRepos',
 
-  stacks: [],
-
   mpacks: [],
 
   repos: [],
@@ -46,115 +44,116 @@ App.WizardCustomProductReposController = 
App.WizardStepController.extend({
     return false;
   },
 
+  getRegisteredMpackInfo: function () {
+    return App.ajax.send({
+      name: 'mpack.get_all_registered',
+      sender: this
+    })
+  },
+
   /**
-   * Pulls os and repo info from App.Stack and matches it up with selected 
mpacks.
-   * Adds the built up object to the mpacks array.
-   * Populates repos array.
-   * Populates operatingSystems array.
+   * Populates mpacks array, repos array, and operatingSystems array based on 
info about registered mpacks.
    */
   loadStep: function () {
-    const selectedMpacks = this.get('content.selectedMpacks');
-    const stacks = [];
-
-    App.Stack.find().forEach(stack => {
-      const mpack = selectedMpacks.find(mpack => mpack.name === 
stack.get('stackName') && mpack.version === stack.get('stackVersion'));
-
-      if (mpack) {
-        stacks.push(Em.Object.create({
-          id: stack.get('id'),
-          name: mpack.name,
-          version: mpack.version,
-          operatingSystems: 
stack.get('operatingSystems').get('content').map((item, index) => {
-            const os = stack.get('operatingSystems').objectAtContent(index);
+    this.getRegisteredMpackInfo().then(registeredMpacks => {
+      const selectedMpacks = this.get('content.selectedMpacks');
+      const mpacks = [];
+  
+      registeredMpacks.items.forEach(mpack => {
+        const selectedMpack = selectedMpacks.find(selectedMpack => 
selectedMpack.name === mpack.MpackInfo.mpack_name && selectedMpack.version === 
mpack.MpackInfo.mpack_version);
+        
+        mpacks.push(Em.Object.create({
+          id: mpack.MpackInfo.id,
+          name: mpack.MpackInfo.mpack_name,
+          displayName: mpack.MpackInfo.mpack_display_name,
+          publicUrl: selectedMpack.publicUrl,
+          downloadUrl: selectedMpack.downloadUrl,
+          version: mpack.MpackInfo.mpack_version,
+          operatingSystems: mpack.default_operating_systems.map(os => {
+            //determines if the OS was selected in the database (as when the 
mpack is initially registered)            
+            let initiallySelected;
+            if (mpack.operating_systems) {
+              initiallySelected = mpack.operating_systems.find(mpackOs => 
mpackOs.OperatingSystems.os_type === os.OperatingSystems.os_type);
+            }
+
+            //checks if the OS was selected in the UI
             let selectedOs;
-            if (mpack.operatingSystems) {
-              selectedOs = mpack.operatingSystems.find(mpackOs => mpackOs.type 
=== os.get('osType'));
+            if (selectedMpack && selectedMpack.operatingSystems) {
+              selectedOs = selectedMpack.operatingSystems.find(mpackOs => 
mpackOs.type === os.OperatingSystems.os_type);
             }
 
             return Em.Object.create({
-              type: os.get('osType'),
+              postdata: os.OperatingSystems,
+              type: os.OperatingSystems.os_type,
+              initiallySelected: initiallySelected ? true : false,
               selected: selectedOs ? true : false,
               isFirstSelected: false,
               isLastSelected: false,
-              repos: os.get('repositories').get('content').map((item, index, 
repos) => {
-                const repo = os.get('repositories').objectAtContent(index);
+              repos: os.OperatingSystems.repositories.map((repo, index, repos) 
=> {
                 let downloadUrl;
 
-                if (selectedOs) {
-                  const selectedRepo = selectedOs.repos.find(mpackRepo => 
mpackRepo.id === repo.get('repoId'));
+                if (selectedOs && selectedOs.repos) {
+                  const selectedRepo = selectedOs.repos.findProperty('repoId', 
repo.repo_id);
+                  
                   if (selectedRepo) {
                     downloadUrl = selectedRepo.downloadUrl;
-                  }  
+                  }
                 }
 
                 return Em.Object.create({
-                  id: 
`${mpack.name}-${mpack.version}-${os.get('osType')}-${repo.get('repoId')}`, 
//this is a unique ID used in client logic
-                  repoId: repo.get('repoId'), //this is the repo ID used by 
the server and displayed in the UI
-                  name: repo.get('repoName'),
-                  publicUrl: repo.get('baseUrlInit'),
-                  downloadUrl: downloadUrl || repo.get('baseUrl'),
-                  unique: repo.get('unique'), //this is a value that is only 
used by the server, but we need to preserve it
+                  id: 
`${mpack.MpackInfo.mpack_name}-${mpack.MpackInfo.mpack_version}-${os.OperatingSystems.os_type}-${repo.repo_id}`,
 //this is a unique ID used in client logic
+                  repoId: repo.repo_id, //this is the repo ID used by the 
server and displayed in the UI
+                  name: repo.repo_name,
+                  publicUrl: repo.base_url,
+                  downloadUrl: downloadUrl || repo.base_url,
                   isFirst: index === 0,
                   isLast: index === repos.length - 1
                 });
               })
             });
           })
-        }));
-      }
-    });
-    this.set('stacks', stacks);
-
-    const mpacks = [];
-    selectedMpacks.forEach(mpack => {
-      const stack = stacks.find(stack => stack.get('name') === mpack.name && 
stack.get('version') === mpack.version);
-      mpacks.pushObject(Em.Object.create({
-        id: stack.get('id'), //this is actually the stack id from App.Stack, 
which is actually the repository_version id in the database, which is an integer
-        name: mpack.name,
-        displayName: mpack.displayName,
-        publicUrl: mpack.publicUrl,
-        downloadUrl: mpack.downloadUrl,
-        version: mpack.version,
-        operatingSystems: stack ? stack.operatingSystems : []
-      }));
-    });
-    this.set('mpacks', mpacks);
-
-    const repos = this.get('mpacks').reduce(
-      (repos, mpack) => repos.concat(
-        mpack.get('operatingSystems').reduce(
-          (repos, os) => repos.concat(
-            os.get('repos')
+        }))
+      });
+      this.set('mpacks', mpacks);
+
+      const repos = mpacks.reduce(
+        (repos, mpack) => repos.concat(
+          mpack.get('operatingSystems').reduce(
+            (repos, os) => repos.concat(
+              os.get('repos')
+            ),
+            [])
           ),
-          [])
-        ),
-      []
-    );
-    this.set('repos', repos);
+        []
+      );
+      this.set('repos', repos);
 
-    const uniqueOperatingSystems = {};
-    mpacks.forEach(mpack => {
-      mpack.get('operatingSystems').forEach(os => {
-        const osType = os.get('type');
-        uniqueOperatingSystems[osType]
-          ? uniqueOperatingSystems[osType].mpacks.pushObject(mpack)
-          : uniqueOperatingSystems[osType] = {
-              selected: os.get('selected'),
-              mpacks: [mpack]
-            };
-      })
-    });
-    
-    const operatingSystems = [];
-    for (let osType in uniqueOperatingSystems) {
-      operatingSystems.pushObject(Em.Object.create({
-        type: osType,
-        selected: uniqueOperatingSystems[osType].selected,
-        mpacks: uniqueOperatingSystems[osType].mpacks
-      }))
-    }
-    operatingSystems.sort((a, b) => 
a.get('type').localeCompare(b.get('type')));
-    this.set('operatingSystems', operatingSystems);
+      const uniqueOperatingSystems = {};
+      mpacks.forEach(mpack => {
+        mpack.get('operatingSystems').forEach(os => {
+          const osType = os.get('type');
+          uniqueOperatingSystems[osType]
+            ? uniqueOperatingSystems[osType].mpacks.pushObject(mpack)
+            : uniqueOperatingSystems[osType] = {
+                selected: os.get('selected'),
+                mpacks: [mpack]
+              };
+        })
+      });
+      
+      const operatingSystems = [];
+      for (let osType in uniqueOperatingSystems) {
+        operatingSystems.pushObject(Em.Object.create({
+          type: osType,
+          selected: uniqueOperatingSystems[osType].selected,
+          mpacks: uniqueOperatingSystems[osType].mpacks
+        }))
+      }
+      operatingSystems.sort((a, b) => 
a.get('type').localeCompare(b.get('type')));
+      this.set('operatingSystems', operatingSystems);
+    },
+      
+    this.wizardController.addErrors);
   },
 
   /**
@@ -250,36 +249,80 @@ App.WizardCustomProductReposController = 
App.WizardStepController.extend({
     this.set('content.selectedMpacks', selectedMpacks);
 
     const useRedHatSatellite = 
this.get('content.downloadConfig.useRedHatSatellite')
-    const updateRepoPromises = mpacks.map(mpack => {
-      const repoToUpdate = {
-        id: mpack.id, //this is actually the stack id from App.Stack, which is 
actually the repository_version id in the database, which is an integer
-        stackName: mpack.name,
-        stackVersion: mpack.version
-      }
-
-      const repo = Em.Object.create({
-        useRedhatSatellite: useRedHatSatellite,
-        operatingSystems: mpack.get('operatingSystems').map(os =>
-          Em.Object.create({
-            osType: os.type,
-            repositories: os.get('repos').map(repo =>
-              Em.Object.create({
-                baseUrlInit: repo.get('publicUrl'),
-                baseUrl: repo.get('downloadUrl'),
-                repoId: repo.get('repoId'),
-                repoName: repo.get('name'),
-                unique: repo.get('unique') //this is a value that is only used 
by the server, but we need to preserve it
-              })
-            )
-          })
-        )
+    
+    const osRepoPromises = [];
+    mpacks.forEach(mpack => {
+      mpack.get('operatingSystems').forEach(os => {
+        const osRepos = os.postdata;
+
+        if (os.selected) {
+          osRepos.is_ambari_managed = !useRedHatSatellite;
+          osRepos.repositories.forEach(repository => {
+            const repo = os.repos.findProperty('repoId', repository.repo_id);
+            repository.base_url = repo.get('downloadUrl');
+          });
+          if (os.initiallySelected === true) { //OS was initially selected and 
is still selected, so we are doing an update
+            osRepoPromises.push(this.updateOsRepos(mpack.get('id'), 
osRepos.os_type, { OperatingSystems: osRepos }));
+          } else { //OS is newly selected, so we are doing a create
+            osRepoPromises.push(this.createOsRepos(mpack.get('id'), 
osRepos.os_type, { OperatingSystems: osRepos }));
+          }
+        } else {
+          if (os.initiallySelected === true) { //OS was initially selected and 
is no longer selected, so we are doing a delete
+            osRepoPromises.push(this.deleteOsRepos(mpack.get('id'), 
osRepos.os_type));
+          }
+        }
       });
-
-      this.get('wizardController').updateRepoOSInfo(repoToUpdate, repo)
     });
 
-    $.when(...updateRepoPromises).then(() => {
+    $.when(...osRepoPromises).then(() => {
       App.router.send('next');  
-    });
+    }, () => 
this.get('wizardController').addError(Em.i18n.t('installer.error.mpackOsModifications')));
+  },
+
+  createOsRepos: function (mpack, os, data) {
+    var deferred = $.Deferred();
+    
+    App.ajax.send({
+      name: 'mpack.create_os_repos',
+      sender: this,
+      data: {
+        mpack: mpack,
+        os: os,
+        data: data
+      }
+    }).then(deferred.resolve, deferred.reject);
+
+    return deferred.promise();
+  },
+
+  updateOsRepos: function (mpack, os, data) {
+    var deferred = $.Deferred();
+    
+    App.ajax.send({
+      name: 'mpack.update_os_repos',
+      sender: this,
+      data: {
+        mpack: mpack,
+        os: os,
+        data: data
+      }
+    }).then(deferred.resolve, deferred.reject);
+
+    return deferred.promise();
+  },
+
+  deleteOsRepos: function (mpack, os) {
+    var deferred = $.Deferred();
+    
+    App.ajax.send({
+      name: 'mpack.delete_os_repos',
+      sender: this,
+      data: {
+        mpack: mpack,
+        os: os
+      }
+    }).then(deferred.resolve, deferred.reject);
+
+    return deferred.promise();
   }
 });
diff --git a/ambari-web/app/controllers/wizard/downloadMpacks_controller.js 
b/ambari-web/app/controllers/wizard/downloadMpacks_controller.js
index 08e85c1..915bb73 100644
--- a/ambari-web/app/controllers/wizard/downloadMpacks_controller.js
+++ b/ambari-web/app/controllers/wizard/downloadMpacks_controller.js
@@ -32,6 +32,7 @@ App.WizardDownloadMpacksController = 
App.WizardStepController.extend({
     selectedMpacks.forEach(mpack => {
       this.get('mpacks').pushObject(Em.Object.create({
         name: mpack.name,
+        version: mpack.version,
         displayName: mpack.displayName,
         url: mpack.downloadUrl,
         inProgress: true,
@@ -118,13 +119,6 @@ App.WizardDownloadMpacksController = 
App.WizardStepController.extend({
     }
   },
 
-  getRegisteredMpacks: function () {
-    return App.ajax.send({
-      name: 'mpack.get_registered_mpacks',
-      sender: this
-    });
-  },
-
   isSubmitDisabled: function () {
     const mpacks = this.get('mpacks');
     return App.get('router.btnClickInProgress')
@@ -137,21 +131,13 @@ App.WizardDownloadMpacksController = 
App.WizardStepController.extend({
       return;
     }
 
-    if (!this.get('isSubmitDisabled')) {
-      //get info about stacks from version definitions and save to Stack model
-      this.getRegisteredMpacks().then(mpacks => {
-        const stackVersionsRegistered = mpacks.items.map(mpack => 
this.get('wizardController').createMpackStackVersion
-          (
-            mpack.version[0].Versions.stack_name,
-            mpack.version[0].Versions.stack_version
-          )
-        );
-
-        $.when(...stackVersionsRegistered).always(() => { //this uses always() 
because the api call made by createMpackStackVersion will return a 500 error
-                                                          //if the stack 
version has already been registered, but we want to proceed anyway
-          App.router.send('next');
-        });
-      });
+    //TODO: mpacks - For now, hard coding this to use the name and version of 
the first stack/mpack that successfully registered. 
+    //We need to get rid of the concept of "selected stack".
+    const selectedStack = this.get('mpacks').findProperty('succeeded');
+    if (selectedStack) {
+      this.set('content.selectedStack', { name: selectedStack.get('name'), 
version: selectedStack.get('version') });
     }
+
+    App.router.send('next');
   }
 });
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 2ace68a..99034e5 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -31,7 +31,6 @@ Em.I18n.translations = {
     '<br/>Alternatively login as an Ambari local user using the local login 
page.<br />' +
     '<a href="{0}" target="_blank">{0}</a>',
 
-  'app.loadingPlaceholder': 'Loading...',
   'app.versionMismatchAlert.title': 'Ambari Server / Web Client Version 
Mismatch',
   'app.versionMismatchAlert.body': 'Ambari Server and Web Client versions do 
not match:<br> ' +
     '<br>Ambari Server: <strong>{0}</strong>' +
@@ -119,14 +118,12 @@ Em.I18n.translations = {
   'common.configGroup': 'Config Group',
   'common.configs': "Configs",
   'common.configuration': "Configuration",
-  'common.confirm.password': 'Confirm Password',
   'common.confirm': 'Confirm',
   'common.continueAnyway': 'Continue Anyway',
   'common.copy':'Copy',
   'common.cores.cpu': 'Cores (CPU)',
   'common.cores': 'Cores',
   'common.cpu':'CPU',
-  'common.critical.error': 'Critical',
   'common.critical': 'Critical',
   'common.csv': 'Save as CSV',
   'common.current': 'Current',
@@ -182,7 +179,6 @@ Em.I18n.translations = {
   'common.filters': 'Filters',
   'common.finalize': "Finalize",
   'common.free': 'free',
-  'common.freeStorage': 'Free Storage',
   'common.from.version': 'From Version',
   'common.fullLogPopup.clickToCopy': 'Click to Copy',
   'common.generate.blueprint':'Generate Blueprint',
@@ -233,18 +229,18 @@ Em.I18n.translations = {
   'common.message':'Message',
   'common.metrics':'Metrics',
   'common.milliseconds': "Milliseconds",
-  'common.minute.ago': 'less than a minute ago',
   'common.minutes': "Minutes",
   'common.misc': 'Misc',
   'common.more': 'More...',
   'common.move':'Move',
   'common.mpack': 'Management Pack',
+  'common.freeStorage': 'Free Storage',
+  'common.noHostsFound': 'No Hosts found.',
   'common.na': 'n/a',
   'common.name':'Name',
   'common.new': 'New',
   'common.next': 'Next',
   'common.noData': 'No Data',
-  'common.noHostsFound': 'No Hosts found.',
   'common.noLink': 'No Links',
   'common.notAvailable': 'Not Available',
   'common.notes': 'Notes',
@@ -301,7 +297,6 @@ Em.I18n.translations = {
   'common.retry':'Retry',
   'common.reUpgrade': 'Retry Upgrade',
   'common.revert': 'Revert',
-  'common.review': 'Review',
   'common.rollBack':'Rollback',
   'common.rolling.downgrade': 'Rolling Downgrade',
   'common.rolling': 'Rolling',
@@ -368,7 +363,6 @@ Em.I18n.translations = {
   'common.use': 'Use',
   'common.used': 'used',
   'common.user': 'User',
-  'common.username': 'Username',
   'common.users': 'Users',
   'common.userSettings': 'User Settings',
   'common.value': 'Value',
@@ -382,6 +376,7 @@ Em.I18n.translations = {
   'common.warning': 'Warning',
   'common.with': 'with',
   'common.zookeeper':'ZooKeeper',
+  'common.critical.error': 'Critical',
 
   'models.alert_instance.tiggered.verbose': "Occurred on {0} <br> Checked on 
{1}",
   'models.alert_definition.triggered.verbose': "Occurred on {0}",
@@ -445,7 +440,6 @@ Em.I18n.translations = {
   'hostPopup.setRackId.invalid': 'Should start with a forward slash it may 
include alphanumeric chars, dots, dashes and forward slashes. Should be less 
than 255 symbols.',
   'hostPopup.RackId': 'Rack',
   'hostPopup.recommendation.beforeDecommission': '{0} Maintenance Mode is pre 
required for decommissioning.',
-  'hostPopup.default.userName': 'none',
 
   'question.sure':'Are you sure?',
   'question.sure.regenerateKeytab.host': 'Are you sure you want to regenerate 
keytab file operations for a {0} host?',
@@ -514,7 +508,6 @@ Em.I18n.translations = {
   'popup.dependent.configs.table.saveProperty': 'Save property',
   'popup.dependent.configs.table.initValue': 'Initial value',
   'popup.dependent.configs.table.currentValue': 'Current Value',
-  'popup.dependent.configs.table.originalValue': 'Original Value',
   'popup.dependent.configs.table.recommendedValue': 'Recommended Value',
   'popup.dependent.configs.table.newValue': 'New Value',
   'popup.dependent.configs.table.undefined': 'Property undefined',
@@ -616,7 +609,7 @@ Em.I18n.translations = {
   'installer.noHostsAssigned':'No host assigned',
   'installer.slaveComponentHosts.selectHosts':'select hosts for this group',
   'installer.slaveComponentHostsPopup.header':'Select which hosts should 
belong to which {0} group',
-
+  'installer.error.mpackOsModifications': 'Failed to modify mpack repos.',
   'installer.error.mpackServiceInfo': 'Failed to load mpack service info.',
   'installer.error.mpackStackInfo': 'Failed to load stack info.',
     
@@ -1031,13 +1024,6 @@ Em.I18n.translations = {
 
   'installer.step7.header':'Customize Services',
   'installer.step7.body':'We have come up with recommended configurations for 
the services you selected. Customize them as you see fit.',
-  'installer.step7.credentialsTab.body':'Please provide credentials for these 
services',
-  'installer.step7.databasesTab.body':'Please choose and configure the 
appropriate databases for these services',
-  'installer.step7.databasesTab.radioButton.default':'Use Ambari Database',
-  'installer.step7.databasesTab.radioButton.custom':'Use Custom Database',
-  'installer.step7.credentialsTab.usersGroups':'Users/Groups',
-  'installer.step7.credentialsTab.usernames':'Usernames',
-  'installer.step7.accountsTab.body': 'Please review these settings for 
Service Accounts',
   'installer.step7.attentionNeeded':'<b>Attention:</b> Some configurations 
need your attention before you can proceed.',
   'installer.step7.noIssues':'All configurations have been addressed.',
   'installer.step7.showPropertiesWithIssues':'Show me properties with issues',
@@ -1062,8 +1048,7 @@ Em.I18n.translations = {
   'installer.step7.popup.validation.failed.body': 'Some services are not 
properly configured. You have to change the highlighted configs according to 
the recommended values.',
   'installer.step7.popup.validation.request.failed.body': 'The configuration 
changes could not be validated for consistency due to an unknown error.  Your 
changes have not been saved yet.  Would you like to proceed and save the 
changes?',
   'installer.step7.popup.validation.warning.header': 'Configurations',
-  'installer.step7.popup.validation.issues.title': 'Highly Recommended 
Configurations',
-  'installer.step7.popup.validation.issues.body': 'Please review the folowing 
recommended changes, and click on the property name to change its value.',
+  'installer.step7.popup.validation.issues.body': 'The following configuration 
changes are highly recommended, but can be skipped.',
   'installer.step7.popup.validation.criticalIssues.body': 'You must correct 
the following critical issues before proceeding:',
   'installer.step7.popup.oozie.derby.warning': 'Derby is not recommended for 
production use. With Derby, Oozie Server HA and concurrent connection support 
will not be available.',
   'installer.step7.oozie.database.new': 'New Derby Database',
@@ -1089,10 +1074,7 @@ Em.I18n.translations = {
   'installer.step7.missing.service.body': '{0} service should be added to the 
cluster to {1}.',
   'assign.master.popup.header':'Select {0} host',
   'assign.master.popup.cancel.body':'Not selecting {0} host will disable 
interactive query.',
-  'installer.step7.recommendations.popover.header': 'Review Recommendations',
-  'installer.step7.recommendations.popover.message': '<p>Based on your 
configuration changes, Ambari is recommending the following dependent 
configuration changes. Ambari has updated all checked configuration changes to 
the <strong>Recommended Value</strong>. Uncheck any configuration to retain the 
<strong>Original Value</strong>.</p>',
-  'installer.step7.requirements.popover.header': 'Required Configurations',
-  'installer.step7.requirements.popover.message': '<p>The following properties 
must be set to proceed with the install.</p>',
+
 
   'installer.step8.header': 'Review',
   'installer.step8.body': 'Please review the configuration before 
installation',
@@ -1754,37 +1736,6 @@ Em.I18n.translations = {
   'admin.ra_highAvailability.closePopup':'Enable Ranger Admin HA Wizard is in 
progress. You must allow the wizard to complete for Ambari to be in usable 
state. ' +
   'If you choose to quit, you must follow manual instructions to complete or 
revert enabling Ranger Admin HA as documented in the Ambari User Guide. Are you 
sure you want to exit the wizard?',
 
-  'admin.nameNodeFederation.button.enable':'Add New HDFS Namespace',
-  'admin.nameNodeFederation.wizard.header': 'Add New HDFS Namespace',
-  'admin.nameNodeFederation.wizard.step1.header': 'Get Started',
-  'admin.nameNodeFederation.wizard.step1.body':'This wizard will walk you 
through the process of setting up a new Highly Available NameNode pair that 
will be used to create a new HDFS namespace, allowing you to use Ambari to 
manage multiple HDFS namespaces and take advantage of HDFS Federation.',
-  'admin.nameNodeFederation.wizard.step1.alert':'If you have HBase running, 
please exit this wizard and stop HBase first.',
-  'admin.nameNodeFederation.wizard.step1.nameserviceid':'New Nameservice ID',
-  'admin.nameNodeFederation.wizard.step1.nameserviceid.existing':'Existing 
Nameservice ID',
-  'admin.nameNodeFederation.wizard.step1.nameserviceid.error':'Must consist of 
letters, numbers, and hyphens. Cannot begin or end with a hyphen.',
-  'admin.nameNodeFederation.wizard.step2.header': 'Select Hosts',
-  'admin.nameNodeFederation.wizard.step3.header': 'Review',
-  'admin.nameNodeFederation.wizard.step3.confirm.config.body': '<div 
class="alert alert-info">' +
-    '<p><b>Review Configuration Changes.</b></p>' +
-    'The following lists the configuration changes that will be made by the 
Wizard to enable NameNode Federation. This information is for <b> review only 
</b> and is not editable except for the  <b>dfs.journalnode.edits.dir</b> 
properties' +
-    '</div>',
-  'admin.nameNodeFederation.wizard.step4.header': 'Configure Components',
-  'admin.nameNodeFederation.wizard,step4.save.configuration.note':'This 
configuration is created by Enable NameNode Federation wizard',
-  'admin.nameNodeFederation.wizard.step4.notice.inProgress':'Please wait while 
NameNode Federation Wizard is being deployed.',
-  'admin.nameNodeFederation.wizard.step4.notice.completed':'NameNode 
Federation Wizard has been enabled successfully.',
-  'admin.nameNodeFederation.wizard.step4.task0.title': 'Stop All Services',
-  'admin.nameNodeFederation.wizard.step4.task1.title': 'Reconfigure HDFS',
-  'admin.nameNodeFederation.wizard.step4.task2.title': 'Install Additional 
NameNodes',
-  'admin.nameNodeFederation.wizard.step4.task3.title': 'Install Additional 
ZKFCs',
-  'admin.nameNodeFederation.wizard.step4.task4.title': 'Format NameNode',
-  'admin.nameNodeFederation.wizard.step4.task5.title': 'Format ZKFC',
-  'admin.nameNodeFederation.wizard.step4.task6.title': 'Start ZKFC',
-  'admin.nameNodeFederation.wizard.step4.task7.title': 'Start NameNode',
-  'admin.nameNodeFederation.wizard.step4.task8.title': 'Bootstrap NameNode',
-  'admin.nameNodeFederation.wizard.step4.task9.title': 'Start ZKFC',
-  'admin.nameNodeFederation.wizard.step4.task10.title': 'Start NameNode',
-  'admin.nameNodeFederation.wizard.step4.task11.title': 'Start All Services',
-
   'admin.security.title':'Kerberos security has not been enabled',
   'admin.security.enabled': 'Kerberos security is enabled',
   'admin.security.disabled': 'Kerberos security is disabled',
@@ -1869,10 +1820,10 @@ Em.I18n.translations = {
   'admin.misc.nothingToShow': 'No user accounts to display',
 
   'admin.serviceAutoStart.title': "Service Auto Start",
+  'admin.serviceAutoStart.header': "Service Auto Start Configuration",
   'admin.serviceAutoStart.header.text': "Ambari services can be configured to 
start automatically on system boot. Each service can be configured to start all 
components, masters and workers, or selectively.",
-  'admin.serviceAutoStart.general.switcher': "Auto Start Settings",
+  'admin.serviceAutoStart.body.text': "Auto-Start Services",
   'admin.serviceAutoStart.tooltip.text': "{0} components enabled",
-  'admin.serviceAutoStart.column.autoStart': "Auto Start",
 
   'admin.stackVersions.filter.notInstalled': "Not Installed ({0})",
   'admin.stackVersions.filter.all': "All ({0})",
@@ -2098,7 +2049,6 @@ Em.I18n.translations = {
 
   'services.service.start':'Start',
   'services.service.stop':'Stop',
-  'services.service.allComponents':'All Components',
   'services.service.metrics':'Metrics',
   'services.nothingToAdd':'Nothing to add',
   'services.service.summary.version':'Version',
@@ -2449,8 +2399,6 @@ Em.I18n.translations = {
   'services.service.add':'Add Service',
   'services.service.startAll':'Start All',
   'services.service.stopAll':'Stop All',
-  'services.service.startAllComponents': 'Start all components for {0}',
-  'services.service.stopAllComponents': 'Stop all components for {0}',
   'services.service.restartAllRequired':'Restart All Required',
   'services.service.downloadAllClientConfigs':'Download All Client Configs',
   'services.service.startAll.confirmMsg' : 'You are about to start all 
services',
@@ -2462,25 +2410,20 @@ Em.I18n.translations = {
   'services.service.stop.confirmButton': 'Confirm Stop',
   'services.service.start.confirmButton' : 'Confirm Start',
   'services.service.stop.warningMsg.turnOnMM': 'This will generate alerts as 
the service is stopped. To suppress alerts, turn on Maintenance Mode for {0} 
prior to stopping.',
-  'services.service.stopCertain.warningMsg.turnOnMM': 'This will generate 
alerts as components are stopped. To suppress alerts, turn on Maintenance Mode 
for {0} prior to stopping.',
   'services.service.stop.warningMsg.dependent.services': 'Stopping {0} may 
impair the functioning of its dependent service(s): {1}.',
   'services.service.restartAll.confirmButton': 'Confirm Restart All',
   'services.service.restartAll.confirmMsg': 'You are about to restart {0}',
   'services.service.restartAll.warningMsg.turnOnMM': 'This will trigger alerts 
as the service is restarted. To suppress alerts, turn on Maintenance Mode for 
{0} prior to running restart all',
-  'services.service.restartCertain.warningMsg.turnOnMM': 'This will trigger 
alerts as components are restarted. To suppress alerts, turn on Maintenance 
Mode for {0} prior to running restart all',
-  'services.service.componentsInNameSpace': 'components in {0} namespace',
   'services.service.stop.HDFS.warningMsg.checkPointNA': 'Could not determine 
the age of the last HDFS checkpoint. Please ensure that you have a recent 
checkpoint. Otherwise, the NameNode(s) can take a very long time to start up.',
-  
'services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions.singleHost.login':
 '<br><ol><li>Login to the NameNode host <b>{0}</b>.</li>',
-  
'services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions.multipleHosts.login':
 '<ol><li>Login to the NameNode hosts {0}.</li>',
   'services.service.stop.HDFS.warningMsg.checkPointTooOld.instructions':
+    '<br><ol>' +
+    '<li>Login to the NameNode host <b>{0}</b>.</li>' +
     '<li>Put the NameNode in Safe Mode (read-only mode):' +
-    '<div class="code-snippet">sudo su {0} -l -c \'hdfs dfsadmin -safemode 
enter\'</div></li>' +
+    '<div class="code-snippet">sudo su {1} -l -c \'hdfs dfsadmin -safemode 
enter\'</div></li>' +
     '<li>Once in Safe Mode, create a Checkpoint:' +
-    '<div class="code-snippet">sudo su {0} -l -c \'hdfs dfsadmin 
-saveNamespace\'</div></li>' +
+    '<div class="code-snippet">sudo su {1} -l -c \'hdfs dfsadmin 
-saveNamespace\'</div></li>' +
     '</ol>',
-  'services.service.stop.HDFS.warningMsg.checkPointTooOld': 'The last HDFS 
checkpoint is older than {0} hours. ',
-  'services.service.stop.HDFS.warningMsg.checkPointTooOld.makeSure': 'Make 
sure that you have taken a checkpoint before proceeding. Otherwise, the 
NameNode(s) can take a very long time to start up.',
-  'services.service.stop.HDFS.warningMsg.nameSpaces.checkPointTooOld': 'The 
last HDFS checkpoint is older than {0} hours for the following namespaces:',
+  'services.service.stop.HDFS.warningMsg.checkPointTooOld': 'The last HDFS 
checkpoint is older than {0} hours. Make sure that you have taken a checkpoint 
before proceeding. Otherwise, the NameNode(s) can take a very long time to 
start up.',
   'services.service.config_groups_popup.header':'Manage {0} Configuration 
Groups',
   'services.service.config_groups_popup.notice':'You can apply different sets 
of {{serviceName}} configurations to groups of hosts by managing 
{{serviceName}} Configuration Groups and their host membership.  Hosts 
belonging to a {{serviceName}} Configuration Group have the same set of 
configurations for {{serviceName}}. Each host belongs to one {{serviceName}} 
Configuration Group.',
   'services.service.config_groups_popup.rename':'Rename',
@@ -3122,7 +3065,6 @@ Em.I18n.translations = {
   'dashboard.widgets.HawqSegmentUp': 'HAWQ Segments Live',
   'dashboard.widgets.PxfUp': 'PXF Agents Live',
   'dashboard.widgets.PXFAgents': 'PXF Agents',
-  'dashboard.widgets.nameSpace': 'Namespace',
 
   'dashboard': {
     'widgets': {
diff --git a/ambari-web/app/routes/installer.js 
b/ambari-web/app/routes/installer.js
index ffa392f..e58ebcb 100644
--- a/ambari-web/app/routes/installer.js
+++ b/ambari-web/app/routes/installer.js
@@ -303,16 +303,16 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
         controller.save('selectedServices');
         controller.save('selectedMpacks');
         controller.save('advancedMode');
-        var wizardStep6Controller = router.get('wizardStep6Controller');
+        var wizardSelectMpacksController = 
router.get('wizardSelectMpacksController');
         // Clear subsequent settings if user changed service selections
-        if (!wizardStep6Controller.get('isSaved')) {
+        if (!wizardSelectMpacksController.get('isSaved')) {
           router.get('wizardStep5Controller').clearRecommendations();
           controller.setDBProperty('recommendations', undefined);
           controller.set('content.masterComponentHosts', undefined);
           controller.setDBProperty('masterComponentHosts', undefined);
           controller.clearEnhancedConfigs();
           controller.setDBProperty('slaveComponentHosts', undefined);
-          wizardStep6Controller.set('isClientsSet', false);
+          router.get('wizardStep6Controller').set('isClientsSet', false);
         }
         controller.setStepSaved('selectMpacks');
         const downloadConfig = controller.get('content.downloadConfig');
@@ -412,6 +412,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
       }
       App.set('router.nextBtnClickInProgress', true);
       const controller = router.get('installerController');
+      controller.save('selectedStack');
       const downloadConfig = controller.get('content.downloadConfig');
       if (downloadConfig && downloadConfig.useCustomRepo) {
         router.transitionTo('customProductRepos');
diff --git a/ambari-web/app/utils/ajax/ajax.js 
b/ambari-web/app/utils/ajax/ajax.js
index fcc2f60..bea8617 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -228,6 +228,7 @@ var urls = {
     }
   },
 
+  //This is now legacy and should be replaced by common.service.create.configs 
below
   'common.across.services.configurations': {
     'type': 'PUT',
     'real':'/clusters/{clusterName}',
@@ -240,6 +241,17 @@ var urls = {
     }
   },
 
+  'common.service.create.configs': {
+    'type': 'POST',
+    
'real':'/clusters/{clusterName}/servicegroups/{serviceGroupName}/services/{serviceName}/configurations',
+    'format': function(data) {
+      return {
+        apiPrefix: 'api/v2',
+        data: JSON.stringify(data.data)
+      }
+    }
+  },
+
   'common.request.polling': {
     'real': 
'/clusters/{clusterName}/requests/{requestId}?fields=tasks/Tasks/request_id,tasks/Tasks/command,tasks/Tasks/command_detail,tasks/Tasks/ops_display_name,tasks/Tasks/start_time,tasks/Tasks/end_time,tasks/Tasks/exit_code,tasks/Tasks/host_name,tasks/Tasks/id,tasks/Tasks/role,tasks/Tasks/status,tasks/Tasks/structured_out,Requests/*&tasks/Tasks/stage_id={stageId}',
     'mock': '/data/background_operations/host_upgrade_tasks.json'
@@ -340,32 +352,6 @@ var urls = {
     }
   },
 
-  'common.service.host_component.update': {
-    'real': '/clusters/{clusterName}/host_components',
-    'mock': '',
-    'type': 'PUT',
-    'format': function (data) {
-      return {
-        data: JSON.stringify({
-          RequestInfo: {
-            context: data.context,
-            operation_level: {
-              level: 'SERVICE',
-              cluster_name: data.clusterName,
-              service_name: data.serviceName
-            },
-            query: data.query
-          },
-          Body: {
-            HostRoles: {
-              state: data.state
-            }
-          }
-        })
-      }
-    }
-  },
-
   'common.host.host_component.passive': {
     'real': 
'/clusters/{clusterName}/hosts/{hostName}/host_components/{componentName}',
     'mock': '',
@@ -580,7 +566,7 @@ var urls = {
   'background_operations.get_most_recent': {
     'real': 
'/clusters/{clusterName}/requests?to=end&page_size={operationsCount}&fields=' +
     
'Requests/end_time,Requests/id,Requests/progress_percent,Requests/request_context,'
 +
-    
'Requests/request_status,Requests/start_time,Requests/cluster_name,Requests/user_name&minimal_response=true',
+    
'Requests/request_status,Requests/start_time,Requests/cluster_name&minimal_response=true',
     'mock': '/data/background_operations/list_on_start.json',
     'testInProduction': true
   },
@@ -1391,7 +1377,7 @@ var urls = {
     }
   },
   'cluster.load_cluster_name': {
-    'real': 
'/clusters?fields=Clusters/security_type,Clusters/version,Clusters/cluster_id',
+    'real': '/clusters?fields=Clusters/security_type,Clusters/version',
     'mock': '/data/clusters/info.json'
   },
   'cluster.load_last_upgrade': {
@@ -2400,7 +2386,7 @@ var urls = {
     mock: '/data/users/privileges_{userName}.json'
   },
   'router.login.clusters': {
-    'real': 
'/clusters?fields=Clusters/provisioning_state,Clusters/security_type,Clusters/version,Clusters/cluster_id',
+    'real': 
'/clusters?fields=Clusters/provisioning_state,Clusters/security_type,Clusters/version',
     'mock': '/data/clusters/info.json'
   },
   'router.login.message': {
@@ -2670,11 +2656,6 @@ var urls = {
     'real': 
'/clusters/{clusterName}/components?fields=ServiceComponentInfo/component_name,ServiceComponentInfo/service_name,ServiceComponentInfo/service_name,ServiceComponentInfo/category,ServiceComponentInfo/recovery_enabled,ServiceComponentInfo/total_count&minimal_response=true',
     'mock': ''
   },
-  'components.get.staleConfigs': {
-    'real': 
'/clusters/{clusterName}/components?host_components/HostRoles/stale_configs=true'
 +
-    '&fields=host_components/HostRoles/host_name&minimal_response=true',
-    'mock': ''
-  },
   'components.update': {
     'real': '/clusters/{clusterName}/components?{urlParams}',
     'mock': '',
@@ -3185,6 +3166,31 @@ var urls = {
     real: '/mpacks?fields=*',
   },
 
+  'mpack.create_os_repos': {
+    real: '/mpacks/{mpack}/operating_systems/{os}',
+    format: function (data) {
+      return {
+        type: 'POST',
+        data: JSON.stringify(data.data)
+      };
+    }
+  },
+
+  'mpack.update_os_repos': {
+    real: '/mpacks/{mpack}/operating_systems/{os}',
+    format: function (data) {
+      return {
+        type: 'PUT',
+        data: JSON.stringify(data.data)
+      };
+    }
+  },
+
+  'mpack.delete_os_repos': {
+    real: '/mpacks/{mpack}/operating_systems/{os}',
+    type: 'DELETE'
+  },
+
   'mpack.create_version_definition': {
     real: '/version_definitions',
     format: function (data) {
@@ -3209,6 +3215,10 @@ var urls = {
     real: 
'/version_definitions?fields=VersionDefinition/*,operating_systems/repositories/Repositories/*,operating_systems/OperatingSystems/*,VersionDefinition/stack_services,VersionDefinition/repository_version',
   },
 
+  'mpack.get_all_registered': {
+    real: '/mpacks?fields=*'
+  },
+
   'registry.all': {
     real: 
'/registries?fields=mpacks/*,mpacks/versions/RegistryMpackVersionInfo/*,scenarios/*'
   },
@@ -3239,7 +3249,6 @@ var urls = {
           selected_scenarios: data.usecases
         })
       };
-
     }
   }
 };
diff --git a/ambari-web/app/views/main/dashboard/widgets.js 
b/ambari-web/app/views/main/dashboard/widgets.js
index 1048c58..ac5298a 100644
--- a/ambari-web/app/views/main/dashboard/widgets.js
+++ b/ambari-web/app/views/main/dashboard/widgets.js
@@ -45,32 +45,35 @@ App.MainDashboardWidgetsView = Em.View.extend(App.Persist, 
App.LocalStorage, App
   setWidgetGroups: function () {
     if (App.get('router.clusterController.isHDFSNameSpacesLoaded')) {
       let groups = [];
-      const hdfsMasterGroups = 
App.HDFSService.find().objectAt(0).get('masterComponentGroups');
-      
this.removeObserver('App.router.clusterController.isHDFSNameSpacesLoaded', 
this, 'setWidgetGroups');
-      if (hdfsMasterGroups.length > 1) {
-        const nameSpacesListItems = hdfsMasterGroups.map(nameSpace => {
-          const {name, title} = nameSpace;
-          return {
-            name,
-            title,
-            isActive: false
-          };
-        });
-        groups.push(Em.Object.create({
-          name: 'nn',
-          title: Em.I18n.t('dashboard.widgets.nameSpace'),
-          serviceName: 'HDFS',
-          subGroups: [
-            {
-              name: '*',
-              title: Em.I18n.t('common.all'),
-              isActive: true
-            },
-            ...nameSpacesListItems
-          ],
-          activeSubGroup: Em.computed.findBy('subGroups', 'isActive', true),
-          allWidgets: this.get('allNameNodeWidgets')
-        }));
+      const hdfsServices = App.HDFSService.find();
+      if(hdfsServices.length > 0) {
+        const hdfsMasterGroups = 
hdfsServices.objectAt(0).get('masterComponentGroups');
+        
this.removeObserver('App.router.clusterController.isHDFSNameSpacesLoaded', 
this, 'setWidgetGroups');
+        if (hdfsMasterGroups.length > 1) {
+          const nameSpacesListItems = hdfsMasterGroups.map(nameSpace => {
+            const { name, title } = nameSpace;
+            return {
+              name,
+              title,
+              isActive: false
+            };
+          });
+          groups.push(Em.Object.create({
+            name: 'nn',
+            title: Em.I18n.t('dashboard.widgets.nameSpace'),
+            serviceName: 'HDFS',
+            subGroups: [
+              {
+                name: '*',
+                title: Em.I18n.t('common.all'),
+                isActive: true
+              },
+              ...nameSpacesListItems
+            ],
+            activeSubGroup: Em.computed.findBy('subGroups', 'isActive', true),
+            allWidgets: this.get('allNameNodeWidgets')
+          }));
+        }
       }
       this.set('widgetGroups', groups);
       this.get('widgetGroupsDeferred').resolve();

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to