You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2018/06/14 12:41:21 UTC

[ambari] branch trunk updated: AMBARI-24102 Update the Manage JN wizard step for multiple nameservice scenario. (ababiichuk)

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

ababiichuk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new f1334dc  AMBARI-24102 Update the Manage JN wizard step for multiple nameservice scenario. (ababiichuk)
f1334dc is described below

commit f1334dcdee050598019af49c4aef90c6d3f85871
Author: ababiichuk <ab...@hortonworks.com>
AuthorDate: Thu Jun 14 15:31:24 2018 +0300

    AMBARI-24102 Update the Manage JN wizard step for multiple nameservice scenario. (ababiichuk)
---
 .../journalNode/step3_controller.js                | 58 ++++++++++++++++-
 .../highAvailability/nameNode/step4_controller.js  | 29 +++++----
 ambari-web/app/messages.js                         | 31 +++++++---
 .../admin/highAvailability/journalNode/step3.hbs   | 14 +++--
 ambari-web/app/utils/ajax/ajax.js                  |  4 ++
 .../highAvailability/journalNode/step3_view.js     | 72 +++++++++++++++++++++-
 6 files changed, 180 insertions(+), 28 deletions(-)

diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step3_controller.js
index 6e73fc0..de9fc63 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step3_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step3_controller.js
@@ -19,5 +19,61 @@
 var App = require('app');
 
 App.ManageJournalNodeWizardStep3Controller = App.HighAvailabilityWizardStep4Controller.extend({
-  name: 'manageJournalNodeWizardStep3Controller'
+  name: 'manageJournalNodeWizardStep3Controller',
+
+  isActiveNameNodesStarted: true,
+
+  isHDFSNameSpacesLoaded: Em.computed.alias('App.router.clusterController.isHDFSNameSpacesLoaded'),
+
+  isDataLoadedAndNextEnabled: Em.computed.and('isNextEnabled', 'isHDFSNameSpacesLoaded'),
+
+  pullCheckPointsStatuses: function () {
+    if (this.get('isHDFSNameSpacesLoaded')) {
+      this.removeObserver('isHDFSNameSpacesLoaded', this, 'pullCheckPointsStatuses');
+      const hdfsModel = App.HDFSService.find('HDFS'),
+        nameSpaces = hdfsModel.get('masterComponentGroups'),
+        nameSpacesCount = nameSpaces.length;
+      if (nameSpacesCount > 1) {
+        let hostNames = hdfsModel.get('activeNameNodes').mapProperty('hostName');
+        if (hostNames.length < nameSpacesCount) {
+          nameSpaces.forEach(nameSpace => {
+            const {hosts} = nameSpace,
+              hasActiveNameNode = hosts.some(hostName => hostNames.contains(hostName));
+            if (!hasActiveNameNode) {
+              const hostForNameSpace = hosts.find(hostName => {
+                  return App.HostComponent.find(`NAMENODE_${hostName}`).get('workStatus') === 'STARTED';
+                }) || hosts[0];
+              hostNames.push(hostForNameSpace);
+            }
+          });
+        }
+        App.ajax.send({
+          name: 'admin.high_availability.getNnCheckPointsStatuses',
+          sender: this,
+          data: {
+            hostNames
+          },
+          success: 'checkNnCheckPointsStatuses'
+        });
+      } else {
+        this.pullCheckPointStatus();
+      }
+    } else {
+      this.addObserver('isHDFSNameSpacesLoaded', this, 'pullCheckPointsStatuses');
+    }
+  },
+
+  checkNnCheckPointsStatuses: function (data) {
+    const items = Em.getWithDefault(data, 'items', []),
+      isNextEnabled = items.length && items.every(this.getNnCheckPointStatus);
+    this.setProperties({
+      isActiveNameNodesStarted: items.length && items.everyProperty('HostRoles.desired_state', 'STARTED'),
+      isNextEnabled
+    });
+    if (!isNextEnabled) {
+      window.setTimeout(() => {
+        this.pullCheckPointsStatuses();
+      }, this.POLL_INTERVAL);
+    }
+  }
 });
\ No newline at end of file
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js
index 5cf3880..2786f00 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js
@@ -46,19 +46,26 @@ App.HighAvailabilityWizardStep4Controller = Em.Controller.extend({
 
   checkNnCheckPointStatus: function (data) {
     this.set('isNameNodeStarted', data.HostRoles.desired_state === 'STARTED');
-    var self = this;
-    var journalTransactionInfo = $.parseJSON(Em.get(data, 'metrics.dfs.namenode.JournalTransactionInfo'));
-    var isInSafeMode = !Em.isEmpty(Em.get(data, 'metrics.dfs.namenode.Safemode'));
-    // in case when transaction info absent or invalid return 2 which will return false in next `if` statement
-    journalTransactionInfo = !!journalTransactionInfo ? (parseInt(journalTransactionInfo.LastAppliedOrWrittenTxId) - parseInt(journalTransactionInfo.MostRecentCheckpointTxId)) : 2;
-    if (journalTransactionInfo <= 1 && isInSafeMode) {
-      this.set("isNextEnabled", true);
+    const isNextEnabled = this.getNnCheckPointStatus(data);
+    if (isNextEnabled) {
+      this.set('isNextEnabled', true);
       return;
     }
-    
-    window.setTimeout(function () {
-      self.pullCheckPointStatus();
-    }, self.POLL_INTERVAL);
+
+    window.setTimeout(() => {
+      this.pullCheckPointStatus();
+    }, this.POLL_INTERVAL);
+  },
+
+  getNnCheckPointStatus: function (data) {
+    const isInSafeMode = !Em.isEmpty(Em.get(data, 'metrics.dfs.namenode.Safemode'));
+    let journalTransactionInfo = $.parseJSON(Em.get(data, 'metrics.dfs.namenode.JournalTransactionInfo'));
+    // in case when transaction info absent or invalid return 2 which will return false in next `if` statement
+    journalTransactionInfo = !!journalTransactionInfo
+      ? (parseInt(journalTransactionInfo.LastAppliedOrWrittenTxId)
+        - parseInt(journalTransactionInfo.MostRecentCheckpointTxId))
+      : 2;
+    return journalTransactionInfo <= 1 && isInSafeMode;
   },
 
   done: function () {
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 9fa6a84..edf43f7 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1401,16 +1401,31 @@ Em.I18n.translations = {
   'admin.manageJournalNode.wizard.step7.notice.inProgress': 'Please wait while services are started',
   'admin.manageJournalNode.wizard.step7.notice.completed':'Completed update to JournalNodes.',
 
+  'admin.manageJournalNode.wizard.step3.error.multipleNameSpaces.nameNodes': 'Some NameNodes are in the process of being stopped. Please make sure that NameNodes are running to create checkpoints successfully.',
+  'admin.manageJournalNode.wizard.step3.body.singleNameSpace.safeModeText': 'Put the NameNode in Safe Mode (read-only mode)',
+  'admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.safeModeText': 'Put the NameNodes in Safe Mode (read-only mode)',
+  'admin.manageJournalNode.wizard.step3.body.singleNameSpace.safeModeCommand': 'sudo su {0} -l -c \'hdfs dfsadmin -safemode enter\'',
+  'admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.safeModeCommand': 'sudo su {0} -l -c \'hdfs dfsadmin -fs hdfs://{1} -safemode enter\'',
+  'admin.manageJournalNode.wizard.step3.body.singleNameSpace.checkPointText': 'Once in Safe Mode, create a Checkpoint',
+  'admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.checkPointText': 'Once in Safe Mode, create Checkpoints',
+  'admin.manageJournalNode.wizard.step3.body.singleNameSpace.checkPointCommand': 'sudo su {0} -l -c \'hdfs dfsadmin -saveNamespace\'',
+  'admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.checkPointCommand': 'sudo su {0} -l -c \'hdfs dfsadmin -fs hdfs://{1} -saveNamespace\'',
+  'admin.manageJournalNode.wizard.step3.body.singleNameSpace.proceed': 'You will be able to proceed once Ambari detects that the NameNode is in Safe Mode and the Checkpoint has been created successfully.',
+  'admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.proceed': 'You will be able to proceed once Ambari detects that the NameNodes are in Safe Mode and the Checkpoints have been created successfully.',
+  'admin.manageJournalNode.wizard.step3.body.singleNameSpace.recentCheckPoint': 'If the <b>Next</b> button is enabled before you run the <b>"Step 3: Save Namespace"</b> command, it means there is a recent Checkpoint already and you may proceed without running the <b>"Step 3: Save Namespace"</b> command.',
+  'admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.recentCheckPoint': 'If the <b>Next</b> button is enabled before you run the <b>"Step 3: Save Namespace"</b> commands, it means there are recent Checkpoints already and you may proceed without running the <b>"Step 3: Save Namespace"</b> commands.',
   'admin.manageJournalNode.wizard.step3.body':
   '<ol>' +
-  '<li>Login to the NameNode host <b>{1}</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>' +
-  '<li>Once in Safe Mode, create a Checkpoint:' +
-  '<div class="code-snippet">sudo su {0} -l -c \'hdfs dfsadmin -saveNamespace\'</div></li>' +
-  '<li>You will be able to proceed once Ambari detects that the NameNode is in Safe Mode and the Checkpoint has been created successfully.</li>'+
-  '<div class="alert alert-warn">If the <b>Next</b> button is enabled before you run the <b>"Step 3: Save Namespace"</b> command, it means there is a recent Checkpoint already and you may proceed without running the <b>"Step 3: Save Namespace"</b> command.</div>' +
+  '<li>Login to the NameNode host <b>{0}</b>.</li>' +
+  '<li>{1}:' +
+  '<div class="code-snippet">{2}</div></li>' +
+  '<li>{3}:' +
+  '<div class="code-snippet">{4}</div></li>' +
+  '<li>{5}</li>'+
+  '<div class="alert alert-warn">{6}</div>' +
   '</ol>',
+  'admin.manageJournalNode.wizard.step3.checkPointsNotCreated': 'Checkpoints not created yet',
+  'admin.manageJournalNode.wizard.step3.checkPointsCreated': 'Checkpoints created',
 
   'admin.manageJournalNode.wizard.step5.body':
   '<ol>' +
@@ -1451,7 +1466,7 @@ Em.I18n.translations = {
   'admin.highAvailability.wizard.step2.header':'Select Hosts',
   'admin.highAvailability.wizard.step3.header':'Review',
   'admin.highAvailability.wizard.step4.header':'Create Checkpoint',
-  'admin.highAvailability.wizard.step4.error.nameNode':'NameNode is in the process of being stopped. Please make sure that namenode is running to create checkpoint successfully.',
+  'admin.highAvailability.wizard.step4.error.nameNode':'NameNode is in the process of being stopped. Please make sure that NameNode is running to create checkpoint successfully.',
   'admin.highAvailability.wizard.step5.header':'Configure Components',
   'admin.highAvailability.wizard.step6.header':'Initialize JournalNodes',
   'admin.highAvailability.wizard.step7.header':'Start Components',
diff --git a/ambari-web/app/templates/main/admin/highAvailability/journalNode/step3.hbs b/ambari-web/app/templates/main/admin/highAvailability/journalNode/step3.hbs
index 2c1125b..6b580ad 100644
--- a/ambari-web/app/templates/main/admin/highAvailability/journalNode/step3.hbs
+++ b/ambari-web/app/templates/main/admin/highAvailability/journalNode/step3.hbs
@@ -17,21 +17,25 @@
 }}
 <div id="manage-journal-node-step3" class="wizard-content col-md-9">
   <h4 class="step-title">{{t admin.manageJournalNode.wizard.step3.header}}</h4>
-  {{#unless controller.isNameNodeStarted}}
+  {{#if view.errorText}}
     <p class="step-description">
-        {{t admin.highAvailability.wizard.step4.error.nameNode}}
+      {{view.errorText}}
     </p>
-  {{/unless}}
+  {{/if}}
   <div class="panel panel-default">
     <div class="panel-body">
-      {{{view.step3BodyText}}}
+      {{#if controller.isHDFSNameSpacesLoaded}}
+        {{{view.step3BodyText}}}
+      {{else}}
+        {{view App.SpinnerView}}
+      {{/if}}
     </div>
   </div>
 </div>
 
 <div class="wizard-footer col-md-12">
   <div class="btn-area">
-    <a  {{bindAttr class="controller.isNextEnabled::disabled :btn :btn-success :pull-right"}} {{action done target="controller"}}>{{t common.next}} &rarr;</a>
+    <a {{bindAttr class="controller.isDataLoadedAndNextEnabled::disabled :btn :btn-success :pull-right"}} {{action done target="controller"}}>{{t common.next}} &rarr;</a>
     <span class="pull-right btn-extra-info">{{view.nnCheckPointText}}</span>
   </div>
 </div>
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 6606874..9c36c45 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -1440,6 +1440,10 @@ var urls = {
     'real': '/clusters/{clusterName}/hosts/{hostName}/host_components/NAMENODE',
     'mock': ''
   },
+  'admin.high_availability.getNnCheckPointsStatuses': {
+    'real': '/clusters/{clusterName}/host_components?HostRoles/component_name=NAMENODE&HostRoles/host_name.in({hostNames})&fields=HostRoles/desired_state,metrics/dfs/namenode&minimal_response=true',
+    'mock': ''
+  },
   'admin.high_availability.getJnCheckPointStatus': {
     'real': '/clusters/{clusterName}/hosts/{hostName}/host_components/JOURNALNODE?fields=metrics',
     'mock': ''
diff --git a/ambari-web/app/views/main/admin/highAvailability/journalNode/step3_view.js b/ambari-web/app/views/main/admin/highAvailability/journalNode/step3_view.js
index 8bdfd08..73cd4c2 100644
--- a/ambari-web/app/views/main/admin/highAvailability/journalNode/step3_view.js
+++ b/ambari-web/app/views/main/admin/highAvailability/journalNode/step3_view.js
@@ -21,9 +21,75 @@ var App = require('app');
 
 App.ManageJournalNodeWizardStep3View = App.HighAvailabilityWizardStep4View.extend({
   templateName: require('templates/main/admin/highAvailability/journalNode/step3'),
+
+  didInsertElement: function () {
+    this.get('controller').pullCheckPointsStatuses();
+  },
+
   step3BodyText: function () {
-    var nN = this.get('controller.content.activeNN');
-    return Em.I18n.t('admin.manageJournalNode.wizard.step3.body').format(this.get('controller.content.hdfsUser'), nN.host_name);
-  }.property('controller.content.masterComponentHosts'),
+    const nN = this.get('controller.content.activeNN'),
+      hdfsUser = this.get('controller.content.hdfsUser'),
+      nameSpaces = App.HDFSService.find('HDFS').get('masterComponentGroups').mapProperty('name');
+    let formatArgs = [nN.host_name];
+    if (nameSpaces.length > 1) {
+      formatArgs.push(
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.safeModeText'),
+        nameSpaces.map(ns => {
+          return Em.I18n.t('admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.safeModeCommand')
+            .format(hdfsUser, ns);
+        }).join('<br>'),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.checkPointText'),
+        nameSpaces.map(ns => {
+          return Em.I18n.t('admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.checkPointCommand')
+            .format(hdfsUser, ns);
+        }).join('<br>'),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.proceed'),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.multipleNameSpaces.recentCheckPoint')
+      );
+    } else {
+      formatArgs.push(
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.singleNameSpace.safeModeText'),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.singleNameSpace.safeModeCommand').format(hdfsUser),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.singleNameSpace.checkPointText'),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.singleNameSpace.checkPointCommand').format(hdfsUser),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.singleNameSpace.proceed'),
+        Em.I18n.t('admin.manageJournalNode.wizard.step3.body.singleNameSpace.recentCheckPoint')
+      );
+    }
+    return Em.I18n.t('admin.manageJournalNode.wizard.step3.body').format(...formatArgs);
+  }.property('controller.content.masterComponentHosts', 'controller.isHDFSNameSpacesLoaded'),
+
+  nnCheckPointText: function () {
+    if (this.get('controller.isHDFSNameSpacesLoaded')) {
+      const nameSpaces = App.HDFSService.find('HDFS').get('masterComponentGroups');
+      let key;
+      if (nameSpaces.length > 1) {
+        key = this.get('controller.isNextEnabled')
+          ? 'admin.manageJournalNode.wizard.step3.checkPointsCreated'
+          : 'admin.manageJournalNode.wizard.step3.checkPointsNotCreated';
+      } else {
+        key = this.get('controller.isNextEnabled')
+          ? 'admin.highAvailability.wizard.step4.ckCreated'
+          : 'admin.highAvailability.wizard.step4.ckNotCreated';
+      }
+      return Em.I18n.t(key);
+    } else {
+      return '';
+    }
+  }.property('controller.isHDFSNameSpacesLoaded', 'controller.isNextEnabled'),
 
+  errorText: function () {
+    if (this.get('controller.isHDFSNameSpacesLoaded')) {
+      const nameSpaces = App.HDFSService.find('HDFS').get('masterComponentGroups');
+      if (nameSpaces.length > 1) {
+        return this.get('controller.isActiveNameNodesStarted') ? ''
+          : Em.I18n.t('admin.manageJournalNode.wizard.step3.error.multipleNameSpaces.nameNodes');
+      } else {
+        return this.get('controller.isNameNodeStarted') ? ''
+          : Em.I18n.t('admin.highAvailability.wizard.step4.error.nameNode');
+      }
+    } else {
+      return '';
+    }
+  }.property('controller.isHDFSNameSpacesLoaded', 'controller.isNameNodeStarted', 'controller.isActiveNameNodesStarted')
 });

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