You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2013/08/01 19:23:19 UTC

git commit: AMBARI-2791. NameNode HA Wizard: Review page. (Antonenko Alexander via yusaku)

Updated Branches:
  refs/heads/trunk 55b634d71 -> d8af64c75


AMBARI-2791. NameNode HA Wizard: Review page. (Antonenko Alexander via yusaku)


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

Branch: refs/heads/trunk
Commit: d8af64c754ea68f68df436b59c6608f7c8f8d2e0
Parents: 55b634d
Author: Yusaku Sako <yu...@hortonworks.com>
Authored: Thu Aug 1 10:23:08 2013 -0700
Committer: Yusaku Sako <yu...@hortonworks.com>
Committed: Thu Aug 1 10:23:11 2013 -0700

----------------------------------------------------------------------
 .../admin/highAvailability/step2_controller.js  | 108 ++++++++++++++++-
 .../admin/highAvailability/wizard_controller.js | 120 ++++++++++++++++++-
 ambari-web/app/messages.js                      |  12 ++
 .../app/routes/high_availability_routes.js      |   9 +-
 ambari-web/app/styles/application.less          |   5 +
 .../main/admin/highAvailability/step1.hbs       |   3 +
 .../main/admin/highAvailability/step2.hbs       |  60 +++++++++-
 .../main/admin/highAvailability/step2_view.js   |   4 +-
 8 files changed, 314 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
index fcc0c14..16fe06e 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
@@ -18,5 +18,111 @@
 
 var App = require('app');
 
-App.HighAvailabilityWizardStep2Controller = Em.Controller.extend();
+require('controllers/wizard/step5_controller');
+
+App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
+
+  name:"highAvailabilityWizardStep2Controller",
+
+  /**
+   * Load services info to appropriate variable and return masterComponentHosts
+   * @return Array
+   */
+  masterHostMapping:function () {
+    var mapping = [], mappingObject, self = this, mappedHosts, hostObj, hostInfo;
+    //get the unique assigned hosts and find the master services assigned to them
+
+
+    mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq();
+
+    mappedHosts.forEach(function (item) {
+
+      hostObj = self.get("hosts").findProperty("host_name", item);
+      console.log("Name of the host is: " + hostObj.host_name);
+
+      var masterServices = self.get("selectedServicesMasters").filterProperty("selectedHost", item);
+      masterServices.forEach(function(item){
+        if(item.component_name == "NAMENODE" || item.component_name == "JOURNALNODE"){
+          item.set('color','green');
+        }else{
+          item.set('color','grey');
+        }
+      })
+
+      mappingObject = Ember.Object.create({
+        host_name:item,
+        hostInfo:hostObj.host_info,
+        masterServices:masterServices
+      });
+
+      mapping.pushObject(mappingObject);
+    }, this);
+
+    mapping.sort(this.sortHostsByName);
+
+    return mapping;
+
+  }.property("selectedServicesMasters.@each.selectedHost"),
+
+  /**
+   * Put master components to <code>selectedServicesMasters</code>, which will be automatically rendered in template
+   * @param masterComponents
+   */
+  renderComponents:function (masterComponents) {
+    var services = this.get('content.services')
+      .filterProperty('isInstalled', true).filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
+
+    var result = [];
+
+    var curNameNode = masterComponents.findProperty('component_name',"NAMENODE");
+    curNameNode.isCurNameNode = true;
+    curNameNode.zId = 0;
+
+    //Create JOURNALNODE
+    for (var index = 0; index < 3; index++) {
+      masterComponents.push(
+        {
+          availableHosts: [],
+          component_name: "JOURNALNODE",
+          display_name: "Journal Node",
+          isHiveCoHost: false,
+          isInstalled: false,
+          selectedHost: this.get("hosts")[index].get("host_name"),
+          serviceId: "HDFS",
+          zId: index
+        }
+      )
+    }
+    //Create Additional NameNode
+    masterComponents.push(
+      {
+        availableHosts: [],
+        component_name: "NAMENODE",
+        display_name: "NameNode",
+        isHiveCoHost: false,
+        isInstalled: false,
+        selectedHost: this.get("hosts").mapProperty('host_name').without(curNameNode.selectedHost)[0],
+        serviceId: "HDFS",
+        isAddNameNode: true,
+        zId: 1
+      }
+    )
+
+    masterComponents.forEach(function (item) {
+      var componentObj = Ember.Object.create(item);
+      componentObj.set("availableHosts", this.get("hosts"));
+      result.push(componentObj);
+    }, this);
+
+    this.set("selectedServicesMasters", result);
+
+    var components = result.filterProperty('component_name',"NAMENODE");
+    components.push.apply(components, result.filterProperty('component_name',"JOURNALNODE"));
+
+    this.set('servicesMasters', components);
+    this.rebalanceComponentHosts("NAMENODE");
+    this.rebalanceComponentHosts("JOURNALNODE");
+  }
+
+});
 

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
index b9afa6d..2535171 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
@@ -31,7 +31,12 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
   hideBackButton: true,
 
   content: Em.Object.create({
-    controllerName: 'highAvailabilityWizardController'
+    controllerName: 'highAvailabilityWizardController',
+    cluster: null,
+    hosts: null,
+    services: null,
+    slaveComponentHosts: null,
+    masterComponentHosts: null
   }),
 
   /**
@@ -43,6 +48,116 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
   },
 
   /**
+   * Load services data from server.
+   */
+  loadServicesFromServer: function() {
+    var displayOrderConfig = require('data/services');
+    var apiUrl = App.get('stack2VersionURL');
+    var apiService = this.loadServiceComponents(displayOrderConfig, apiUrl);
+    //
+    apiService.forEach(function(item, index){
+      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
+      apiService[index].isDisabled = apiService[index].isSelected;
+      apiService[index].isInstalled = apiService[index].isSelected;
+    });
+    this.set('content.services', apiService);
+    App.db.setService(apiService);
+  },
+
+  /**
+   * Load confirmed hosts.
+   * Will be used at <code>Assign Masters(step5)</code> step
+   */
+  loadConfirmedHosts: function(){
+    var hosts = App.db.getHosts();
+    if(!hosts || !hosts.length){
+      var hosts = {};
+
+      App.Host.find().forEach(function(item){
+        hosts[item.get('id')] = {
+          name: item.get('id'),
+          cpu: item.get('cpu'),
+          memory: item.get('memory'),
+          disk_info: item.get('diskInfo'),
+          bootStatus: "REGISTERED",
+          isInstalled: true
+        };
+      });
+      App.db.setHosts(hosts);
+    }
+
+    this.set('content.hosts', hosts);
+    console.log('ReassignMasterController.loadConfirmedHosts: loaded hosts', hosts);
+  },
+
+  /**
+   * Load master component hosts data for using in required step controllers
+   */
+  loadMasterComponentHosts: function () {
+    var masterComponentHosts = App.db.getMasterComponentHosts();
+    if(!masterComponentHosts){
+      masterComponentHosts = [];
+      App.HostComponent.find().filterProperty('isMaster', true).forEach(function(item){
+        masterComponentHosts.push({
+          component: item.get('componentName'),
+          hostName: item.get('host.hostName'),
+          isInstalled: true
+        })
+      });
+
+    }
+    this.set("content.masterComponentHosts", masterComponentHosts);
+    console.log("ReassignMasterController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
+  },
+
+  /**
+   * save status of the cluster.
+   * @param clusterStatus object with status,requestId fields.
+   */
+  saveClusterStatus: function (clusterStatus) {
+    var oldStatus = this.toObject(this.get('content.cluster'));
+    clusterStatus = jQuery.extend(oldStatus, clusterStatus);
+    if (clusterStatus.requestId) {
+      clusterStatus.requestId.forEach(function (requestId) {
+        if (clusterStatus.oldRequestsId.indexOf(requestId) === -1) {
+          clusterStatus.oldRequestsId.push(requestId)
+        }
+      }, this);
+    }
+    this.set('content.cluster', clusterStatus);
+    this.save('cluster');
+  },
+
+  /**
+   * Save Master Component Hosts data to Main Controller
+   * @param stepController App.WizardStep5Controller
+   */
+  saveMasterComponentHosts: function (stepController) {
+    var obj = stepController.get('selectedServicesMasters');
+    var masterComponentHosts = [];
+    obj.forEach(function (_component) {
+      masterComponentHosts.push({
+        display_name: _component.get('display_name'),
+        component: _component.get('component_name'),
+        hostName: _component.get('selectedHost'),
+        serviceId: _component.get('serviceId'),
+        isCurNameNode: _component.get('isCurNameNode'),
+        isAddNameNode: _component.get('isAddNameNode'),
+        isInstalled: true
+      });
+    });
+    App.db.setMasterComponentHosts(masterComponentHosts);
+    this.set('content.masterComponentHosts', masterComponentHosts);
+  },
+
+  loadComponentToReassign: function () {
+    var masterComponent = App.db.getMasterToReassign();
+    if (masterComponent) {
+      this.set('content.reassign', masterComponent);
+    }
+  },
+
+  /**
    * Load data for all steps until <code>current step</code>
    */
   loadAllPriorSteps: function () {
@@ -51,6 +166,9 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
       case '4':
       case '3':
       case '2':
+        this.loadServicesFromServer();
+        this.loadMasterComponentHosts();
+        this.loadConfirmedHosts();
       case '1':
         this.load('cluster');
     }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 79d92ce..751d0db 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -645,6 +645,18 @@ Em.I18n.translations = {
   'admin.highAvailability.wizard.step3.header':'Review',
   'admin.highAvailability.wizard.step4.header':'Apply',
 
+  'admin.highAvailability.wizard.step2.body':'Select a host that will be running an additional NameNode.<br/> In addition,' +
+  ' select 3 hosts that will be running JournalNodes to store NameNode edit logs in a fault tolerant maner.',
+  'admin.highAvailability.wizard.step1.body':'We will walk you through enabling NameNode HA with this wizard.<br/>' +
+  'In NameNode HA, you will be running one more NameNode in addition to the current NameNode.  This allows for an ' +
+  'active-standby configuration that automatically fails over if the active NameNode fails.<br/>' +
+  'Note that your current Secondary NameNode will be disabled.<br/>' +
+  'In addition, the NameNodes will be storing the edit logs on multiple JournalNodes for fault tolerance.<br/>' +
+  'Once you make your host selection for NameNodes and JournalNodes and confirm your selection, the wizard ' +
+  'will make necessary changes to enable NameNode HA.<br/>' +
+  'You will be prompted to run manual steps as needed.<br/>' +
+  'Let"s get started.',
+
   'admin.security.title':'Kerberos Security has not been enabled on this cluster.',
   'admin.security.enabled': 'Kerberos security is enabled on the cluster',
   'admin.security.disabled': 'Kerberos security is disabled on the cluster',

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/routes/high_availability_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/high_availability_routes.js b/ambari-web/app/routes/high_availability_routes.js
index 59dfa93..2fb5521 100644
--- a/ambari-web/app/routes/high_availability_routes.js
+++ b/ambari-web/app/routes/high_availability_routes.js
@@ -68,10 +68,13 @@ module.exports = Em.Route.extend({
       controller.setCurrentStep('2');
       controller.dataLoading().done(function () {
         controller.loadAllPriorSteps();
-        controller.connectOutlet('highAvailabilityWizardStep2');
+        controller.connectOutlet('highAvailabilityWizardStep2', controller.get('content'));
       })
     },
     next: function (router) {
+      var controller = router.get('highAvailabilityWizardController');
+      var highAvailabilityWizardStep2Controller = router.get('highAvailabilityWizardStep2Controller');
+      controller.saveMasterComponentHosts(highAvailabilityWizardStep2Controller);
       router.transitionTo('step3');
     },
     back: function (router) {
@@ -86,7 +89,7 @@ module.exports = Em.Route.extend({
       controller.setCurrentStep('3');
       controller.dataLoading().done(function () {
         controller.loadAllPriorSteps();
-        controller.connectOutlet('highAvailabilityWizardStep3');
+        controller.connectOutlet('highAvailabilityWizardStep3',  controller.get('content'));
       })
     },
     next: function (router) {
@@ -104,7 +107,7 @@ module.exports = Em.Route.extend({
       controller.setCurrentStep('4');
       controller.dataLoading().done(function () {
         controller.loadAllPriorSteps();
-        controller.connectOutlet('highAvailabilityWizardStep4');
+        controller.connectOutlet('highAvailabilityWizardStep4',  controller.get('content'));
       })
     },
     back: function (router) {

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index efcdec7..2f00231 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2929,6 +2929,11 @@ table.graphs {
     display: inline-block;
   }
 
+  .host-assignments .grey {
+    background-color: #808080;
+    border: solid 1px #000000;
+  }
+
   .form-horizontal .controls {
     margin-left: 110px;
   }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/templates/main/admin/highAvailability/step1.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/highAvailability/step1.hbs b/ambari-web/app/templates/main/admin/highAvailability/step1.hbs
index def086c..5eca055 100644
--- a/ambari-web/app/templates/main/admin/highAvailability/step1.hbs
+++ b/ambari-web/app/templates/main/admin/highAvailability/step1.hbs
@@ -17,6 +17,9 @@
 }}
 
 <h2>{{t admin.highAvailability.wizard.step1.header}}</h2>
+<p class="alert alert-info">
+  {{t admin.highAvailability.wizard.step1.body}}
+</p>
 <div class="btn-area">
   <a class="btn btn-success pull-right" {{action next}}>{{t common.next}} &rarr;</a>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/highAvailability/step2.hbs b/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
index 8c94c3a..94dd804 100644
--- a/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
+++ b/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
@@ -17,6 +17,64 @@
 }}
 
 <h2>{{t admin.highAvailability.wizard.step2.header}}</h2>
+<div class="alert alert-info">
+  {{t admin.highAvailability.wizard.step2.body}}
+</div>
+<div class="assign-masters">
+  <div class="select-hosts">
+    <form class="form-horizontal" autocomplete="off">
+      <!-- View for array controller -->
+      {{#each servicesMasters}}
+      <div class="control-group">
+        <label class="control-label">
+          {{#if isCurNameNode}}
+            Current
+          {{/if}}
+          {{#if isAddNameNode}}
+            Additional
+          {{/if}}
+            {{display_name}}:
+        </label>
+        <div class="controls">
+          {{view App.SelectHostView
+            contentBinding="availableHosts"
+            optionValuePath="content.host_name"
+            optionLabelPath="content.host_info"
+            selectedHostBinding="selectedHost"
+            componentNameBinding="component_name"
+            zIdBinding="zId"
+            disabledBinding="isInstalled"
+          }}
+          {{#if showAddControl}}
+            {{view App.AddControlView componentNameBinding="component_name"}}
+          {{/if}}
+          {{#if showRemoveControl}}
+            {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
+          {{/if}}
+        </div>
+      </div>
+      {{/each}}
+    </form>
+  </div>
+
+  <div class="host-assignments">
+    {{#each masterHostMapping}}
+    <div class="mapping-box round-corners well">
+      <div class="hostString"><span>{{hostInfo}}</span></div>
+      {{#each masterServices}}
+        <span {{bindAttr class="color :assignedService :round-corners"}}>{{display_name}}</span>
+      {{/each}}
+    </div>
+    {{/each}}
+
+    {{#if remainingHosts}}
+    <div class="remaining-hosts round-corners well">
+      <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
+    {{/if}}
+  </div>
+  <div style="clear: both;"></div>
+</div>
 <div class="btn-area">
-  <a class="btn btn-success pull-right" {{action next}}>{{t common.next}} &rarr;</a>
+
+  <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} &rarr;</a>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/d8af64c7/ambari-web/app/views/main/admin/highAvailability/step2_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/highAvailability/step2_view.js b/ambari-web/app/views/main/admin/highAvailability/step2_view.js
index 334f7de..1b33e4f 100644
--- a/ambari-web/app/views/main/admin/highAvailability/step2_view.js
+++ b/ambari-web/app/views/main/admin/highAvailability/step2_view.js
@@ -19,7 +19,9 @@
 
 var App = require('app');
 
-App.HighAvailabilityWizardStep2View = Em.View.extend({
+require('views/wizard/step5_view');
+
+App.HighAvailabilityWizardStep2View = App.WizardStep5View.extend({
 
   templateName: require('templates/main/admin/highAvailability/step2')