Browse Source

AMBARI-2168. Integrate installing and starting Hadoop 2.0 Services. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1485446 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 years ago
parent
commit
8c908db309

+ 3 - 0
CHANGES.txt

@@ -12,6 +12,9 @@ Trunk (unreleased changes):
 
  NEW FEATURES
 
+ AMBARI-2168. Integrate installing and starting Hadoop 2.0 Services.
+ (yusaku)
+
  AMBARI-2167. Support for displaying various stacks and having the user select
  which stack to install. (yusaku)
 

+ 22 - 2
ambari-web/app/controllers/installer.js

@@ -101,6 +101,7 @@ App.InstallerController = App.WizardController.extend({
       stacks.forEach(function (stack) {
         convertedStacks.pushObject(Ember.Object.create(stack));
       });
+      App.set('currentStackVersion', convertedStacks.findProperty('isSelected').get('name'));
       this.set('content.stacks', convertedStacks);
     } else {
       App.ajax.send({
@@ -133,7 +134,7 @@ App.InstallerController = App.WizardController.extend({
           if (version.Versions.active !== 'false') {
             result.push(
                 Ember.Object.create({
-                  name: version.Versions.stack_name + " " + version.Versions.stack_version,
+                  name: version.Versions.stack_name + "-" + version.Versions.stack_version,
                   isSelected: false
                 })
             );
@@ -141,7 +142,7 @@ App.InstallerController = App.WizardController.extend({
         }, this)
       }
     }, this);
-    var defaultStackVersion = result.findProperty('name', App.defaultStackVersion.replace('-', ' '));
+    var defaultStackVersion = result.findProperty('name', App.defaultStackVersion);
     if (defaultStackVersion) {
       defaultStackVersion.set('isSelected', true)
     } else {
@@ -264,6 +265,7 @@ App.InstallerController = App.WizardController.extend({
    */
   saveStacks: function (stepController) {
     var stacks = stepController.get('content.stacks');
+    App.set('currentStackVersion', stacks.findProperty('isSelected').get('name'));
     App.db.setStacks(stacks);
     this.set('content.stacks', stacks);
   },
@@ -303,6 +305,24 @@ App.InstallerController = App.WizardController.extend({
   finish: function () {
     this.setCurrentStep('0');
     this.clearStorageData();
+  },
+
+  setStepsEnable: function () {
+    for (var i = 0; i <= this.totalSteps; i++) {
+      var step = this.get('isStepDisabled').findProperty('step', i);
+      if (i <= this.get('currentStep')) {
+        step.set('value', false);
+      } else {
+        step.set('value', true);
+      }
+    }
+  }.observes('currentStep'),
+
+  setLowerStepsDisable: function (stepNo) {
+    for (var i = 0; i < stepNo; i++) {
+      var step = this.get('isStepDisabled').findProperty('step', i);
+      step.set('value', true);
+    }
   }
 
 });

+ 32 - 0
ambari-web/app/controllers/wizard/step10_controller.js

@@ -167,6 +167,12 @@ App.WizardStep10Controller = Em.Controller.extend({
         case 'JOBTRACKER' :
           this.loadJt(component);
           break;
+        case 'HISTORYSERVER':
+          this.loadHS(component);
+          break;
+        case 'RESOURCEMANAGER':
+          this.loadRM(component);
+          break;
         case 'ZOOKEEPER_SERVER' :
           // TODO: Fix this; redundant entries and wrong number
           //this.loadZk(component);
@@ -191,6 +197,32 @@ App.WizardStep10Controller = Em.Controller.extend({
     return true;
   },
 
+  loadHS: function (component) {
+    if (component.get('hostName')) {
+      var statement = Em.I18n.t('installer.step10.master.historyServer') + component.get('hostName');
+      this.get('clusterInfo').findProperty('id', 2).get('status').pushObject(Ember.Object.create({
+        id: 1,
+        color: 'text-info',
+        displayStatement: statement
+      }));
+    } else {
+      console.log('ERROR: no host name assigned to HistoryServer component');
+    }
+  },
+
+  loadRM: function (component) {
+    if (component.get('hostName')) {
+      var statement = Em.I18n.t('installer.step10.master.resourceManager') + component.get('hostName');
+      this.get('clusterInfo').findProperty('id', 2).get('status').pushObject(Ember.Object.create({
+        id: 1,
+        color: 'text-info',
+        displayStatement: statement
+      }));
+    } else {
+      console.log('ERROR: no host name assigned to ResourceManager component');
+    }
+  },
+
   loadNn: function (component) {
     if (component.get('hostName')) {
       var statement = Em.I18n.t('installer.step10.master.nameNode') + component.get('hostName');

+ 1 - 1
ambari-web/app/controllers/wizard/step2_controller.js

@@ -271,7 +271,7 @@ App.WizardStep2Controller = Em.Controller.extend({
         this.hide();
       },
       bodyClass: Ember.View.extend({
-        template: Ember.Handlebars.compile('<p>These hosts are already installed on the cluster and will be ignored:</p><p>' + self.get('inputtedAgainHostNames').join(', ') + '</p><p>Do you want to continue?</p>')
+        template: Ember.Handlebars.compile('<p>{{t installer.step2.evaluateStep.installedHosts}}</p><p>' + self.get('inputtedAgainHostNames').join(', ') + '</p><p>{{t installer.step2.evaluateStep.continueConfirm}}</p>')
       })
     });
   },

+ 1 - 1
ambari-web/app/controllers/wizard/step4_controller.js

@@ -78,7 +78,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @return {Boolean}
    */
   needToAddMapReduce: function () {
-    if (this.findProperty('serviceName', 'MAPREDUCE').get('isSelected') === false) {
+    if (this.findProperty('serviceName', 'MAPREDUCE') && this.findProperty('serviceName', 'MAPREDUCE').get('isSelected') === false) {
       var mapreduceDependentServices = this.filter(function (item) {
         return ['PIG', 'OOZIE', 'HIVE'].contains(item.get('serviceName')) && item.get('isSelected', true);
       });

+ 34 - 0
ambari-web/app/controllers/wizard/step5_controller.js

@@ -309,6 +309,36 @@ App.WizardStep5Controller = Em.Controller.extend({
     }
   },
 
+  getResourceManager: function (noOfHosts) {
+    var hosts = this.get('hosts');
+    if (noOfHosts === 1) {
+      return hosts[0];
+    } else if (noOfHosts < 3) {
+      return hosts[1];
+    } else if (noOfHosts <= 5) {
+      return hosts[1];
+    } else if (noOfHosts <= 30) {
+      return hosts[1];
+    } else {
+      return hosts[2];
+    }
+  },
+
+  getHistoryServer: function (noOfHosts) {
+    var hosts = this.get('hosts');
+    if (noOfHosts === 1) {
+      return hosts[0];
+    } else if (noOfHosts < 3) {
+      return hosts[1];
+    } else if (noOfHosts <= 5) {
+      return hosts[1];
+    } else if (noOfHosts <= 30) {
+      return hosts[1];
+    } else {
+      return hosts[2];
+    }
+  },
+
   getHBaseMaster:function (noOfHosts) {
     var hosts = this.get('hosts');
     if (noOfHosts === 1) {
@@ -436,6 +466,10 @@ App.WizardStep5Controller = Em.Controller.extend({
         return this.getSNameNode(noOfHosts).host_name;
       case 'JOBTRACKER':
         return this.getJobTracker(noOfHosts).host_name;
+      case 'HISTORYSERVER':
+        return this.getHistoryServer(noOfHosts).host_name;
+      case 'RESOURCEMANAGER':
+        return this.getResourceManager(noOfHosts).host_name;
       case 'HBASE_MASTER':
         return [this.getHBaseMaster(noOfHosts).host_name];
       case 'OOZIE_SERVER':

+ 8 - 1
ambari-web/app/controllers/wizard/step6_controller.js

@@ -146,7 +146,8 @@ App.WizardStep6Controller = Em.Controller.extend({
    * @return {*}
    */
   isServiceSelected: function (name) {
-    return this.get('content.services').findProperty('serviceName', name).get('isSelected');
+    return this.get('content.services').findProperty('serviceName', name) &&
+      this.get('content.services').findProperty('serviceName', name).get('isSelected');
   },
 
   /**
@@ -210,6 +211,12 @@ App.WizardStep6Controller = Em.Controller.extend({
           label: self.getComponentDisplayName('TASKTRACKER')
         }));
       }
+      if (this.isServiceSelected('YARN')) {
+        headers.pushObject(Em.Object.create({
+          name: 'NODEMANAGER',
+          label: self.getComponentDisplayName('NODEMANAGER')
+        }));
+      }
       if (this.isServiceSelected('HBASE')) {
         headers.pushObject(Em.Object.create({
           name: 'HBASE_REGIONSERVER',

+ 75 - 2
ambari-web/app/controllers/wizard/step8_controller.js

@@ -392,6 +392,13 @@ App.WizardStep8Controller = Em.Controller.extend({
           domain: 'tasktracker-global'
         };
         break;
+      case 'NODEMANAGER':
+        serviceConfig = {
+          name: 'YARN',
+          siteName: 'yarn-site',
+          domain: 'nodemanager-global'
+        };
+        break;
       case 'HBASE_REGIONSERVER':
         serviceConfig = {
           name: 'HBASE',
@@ -475,6 +482,12 @@ App.WizardStep8Controller = Em.Controller.extend({
           case 'MAPREDUCE':
             this.loadMapReduce(serviceObj);
             break;
+          case 'MAPREDUCEv2':
+            this.loadMapReduce2(serviceObj);
+            break;
+          case 'YARN':
+            this.loadYARN(serviceObj);
+            break;
           case 'HIVE':
             this.loadHive(serviceObj);
             break;
@@ -496,7 +509,9 @@ App.WizardStep8Controller = Em.Controller.extend({
           case 'HUE':
             this.loadHue(serviceObj);
             break;
-          /* case 'PIG':
+          /* case 'TEZ':
+           break;
+           case 'PIG':
            this.loadPig(serviceObj);
            break;
            case 'SQOOP':
@@ -578,6 +593,36 @@ App.WizardStep8Controller = Em.Controller.extend({
     this.get('services').pushObject(mrObj);
   },
 
+  loadMapReduce2: function(mrObj){
+    mrObj.get('service_components').forEach(function (_component) {
+      switch (_component.get('display_name')) {
+        case 'History Server':
+          _component.set('component_value', this.get('content.masterComponentHosts').findProperty('component', 'HISTORYSERVER').hostName);
+          break;
+      }
+    }, this);
+    this.get('services').pushObject(mrObj);
+  },
+
+  loadYARN: function(mrObj){
+    mrObj.get('service_components').forEach(function (_component) {
+      switch (_component.get('display_name')) {
+        case 'Node Manager':
+          this.loadNMValue(_component);
+          break;
+        case 'Resource Manager':
+          _component.set('component_value', this.get('content.masterComponentHosts').findProperty('component', 'RESOURCEMANAGER').hostName);
+          break;
+      }
+    }, this);
+    this.get('services').pushObject(mrObj);
+  },
+
+  loadNMValue: function (nmComponent) {
+    var nmHosts = this.get('content.slaveComponentHosts').findProperty('componentName', 'NODEMANAGER');
+    nmComponent.set('component_value', nmHosts.hosts.length + Em.I18n.t('installer.step8.hosts'));
+  },
+
   loadJtValue: function (jtComponent) {
     var jtHostName = this.get('content.masterComponentHosts').findProperty('display_name', jtComponent.display_name);
     jtComponent.set('component_value', jtHostName.hostName);
@@ -990,7 +1035,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var clusterName = this.get('clusterName');
     var url = App.apiPrefix + '/clusters/' + clusterName;
 
-    var stackVersion = (this.get('content.installOptions.localRepo')) ? App.defaultLocalStackVersion : App.defaultStackVersion;
+    var stackVersion = (this.get('content.installOptions.localRepo')) ? App.defaultLocalStackVersion : App.currentStackVersion;
 
     this.ajax({
       type: 'POST',
@@ -1273,6 +1318,18 @@ App.WizardStep8Controller = Em.Controller.extend({
         this.applyConfigurationToSite(this.createMapredQueueAcls());
       }
     }
+    if (selectedServices.someProperty('serviceName', 'MAPREDUCEv2')) {
+      this.applyConfigurationToSite(this.createMrSiteObj());
+      if (App.supports.capacitySchedulerUi) {
+        this.applyConfigurationToSite(this.createMapredQueueAcls());
+      }
+    }
+    if (selectedServices.someProperty('serviceName', 'YARN')) {
+      this.applyConfigurationToSite(this.createYarnSiteObj());
+      if (App.supports.capacitySchedulerUi) {
+        this.applyConfigurationToSite(this.createCapacityScheduler());
+      }
+    }
     if (selectedServices.someProperty('serviceName', 'HBASE')) {
       this.applyConfigurationToSite(this.createHbaseSiteObj());
     }
@@ -1391,6 +1448,18 @@ App.WizardStep8Controller = Em.Controller.extend({
     return {type: 'mapred-site', tag: 'version1', properties: mrProperties};
   },
 
+  createYarnSiteObj: function () {
+    var configs = this.get('configs').filterProperty('filename', 'yarn-site.xml');
+    var mrProperties = {};
+    configs.forEach(function (_configProperty) {
+      mrProperties[_configProperty.name] = _configProperty.value;
+      this._recordHostOverrideFromObj(_configProperty, 'mapred-site', 'version1', this);
+      console.log("STEP*: name of the property is: " + _configProperty.name);
+      console.log("STEP8: value of the property is: " + _configProperty.value);
+    }, this);
+    return {type: 'yarn-site', tag: 'version1', properties: mrProperties};
+  },
+
   createCapacityScheduler: function () {
     var configs = this.get('configs').filterProperty('filename', 'capacity-scheduler.xml');
     var csProperties = {};
@@ -1502,6 +1571,10 @@ App.WizardStep8Controller = Em.Controller.extend({
         return {config: {'global': 'version1', 'core-site': 'version1', 'hdfs-site': 'version1'}};
       case 'MAPREDUCE':
         return {config: {'global': 'version1', 'core-site': 'version1', 'mapred-site': 'version1', 'capacity-scheduler': 'version1', 'mapred-queue-acls': 'version1'}};
+      case 'MAPREDUCEv2':
+        return {config: {'global': 'version1', 'core-site': 'version1', 'mapred-site': 'version1', 'mapred-queue-acls': 'version1'}};
+      case 'YARN':
+        return {config: {'global': 'version1', 'yarn-site': 'version1', 'capacity-scheduler': 'version1'}};
       case 'HBASE':
         return {config: {'global': 'version1', 'hbase-site': 'version1'}};
       case 'OOZIE':

+ 29 - 0
ambari-web/app/data/review_configs.js

@@ -74,6 +74,30 @@ module.exports = [
           })
         ]
       }),
+      Ember.Object.create({
+        service_name: 'MAPREDUCEv2',
+        display_name: 'MapReduce 2',
+        service_components: [
+          Ember.Object.create({
+            display_name: 'History Server',
+            component_value: ''
+          })
+        ]
+      }),
+      Ember.Object.create({
+        service_name: 'YARN',
+        display_name: 'YARN',
+        service_components: [
+          Ember.Object.create({
+            display_name: 'Node Manager',
+            component_value: ''
+          }),
+          Ember.Object.create({
+            display_name: 'Resource Manager',
+            component_value: ''
+          })
+        ]
+      }),
       Ember.Object.create({
         service_name: 'HIVE',
         display_name: 'Hive + HCatalog',
@@ -151,6 +175,11 @@ module.exports = [
           })
         ]
       }),
+      Ember.Object.create({
+        service_name: 'TEZ',
+        display_name: 'TEZ',
+        service_components: []
+      }),
       Ember.Object.create({
         service_name: 'PIG',
         display_name: 'Pig',

+ 48 - 0
ambari-web/app/data/service_components.js

@@ -74,6 +74,54 @@ module.exports = new Ember.Set([
     isClient: true,
     description: 'Client component for MapReduce'
   },
+  {
+    service_name: 'MAPREDUCEv2',
+    component_name: 'MAPREDUCEv2_CLIENT',
+    display_name: 'MapReduce 2 Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'MAPREDUCEv2',
+    component_name: 'HISTORYSERVER',
+    display_name: 'History Server',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'TEZ',
+    component_name: 'TEZ_CLIENT',
+    display_name: 'TEZ Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'YARN',
+    component_name: 'RESOURCEMANAGER',
+    display_name: 'Resource Manager',
+    isMaster: true,
+    isClient: false,
+    description: ''
+  },
+  {
+    service_name: 'YARN',
+    component_name: 'YARN_CLIENT',
+    display_name: 'YARN Client',
+    isMaster: false,
+    isClient: true,
+    description: ''
+  },
+  {
+    service_name: 'YARN',
+    component_name: 'NODEMANAGER',
+    display_name: 'Node Manager',
+    isMaster: false,
+    isClient: false,
+    description: ''
+  },
   {
     service_name: 'ZOOKEEPER',
     component_name: 'ZOOKEEPER_SERVER',

+ 22 - 0
ambari-web/app/data/service_configs.js

@@ -55,6 +55,28 @@ module.exports = [
     configs: configProperties.filterProperty('serviceName', 'MAPREDUCE')
   },
 
+  {
+    serviceName: 'MAPREDUCEv2',
+    displayName: 'MapReduce 2',
+    filename: 'mapred-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'})
+    ],
+    sites: ['global', 'core-site', 'mapred-site', 'mapred-queue-acls'],
+    configs: configProperties.filterProperty('serviceName', 'MAPREDUCEv2')
+  },
+
+  {
+    serviceName: 'YARN',
+    displayName: 'YARN',
+    filename: 'yarn-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'})
+    ],
+    sites: ['global', 'yarn-site', 'capacity-scheduler'],
+    configs: configProperties.filterProperty('serviceName', 'MAPREDUCEv2')
+  },
+
   {
     serviceName: 'HIVE',
     displayName: 'Hive/HCat',

+ 24 - 0
ambari-web/app/data/services.js

@@ -35,6 +35,30 @@ module.exports = [
     canBeSelected: true,
     description: Em.I18n.t('services.mapreduce.description')
   },
+  {
+    serviceName: 'MAPREDUCEv2',
+    displayName: 'MapReduce 2',
+    isDisabled: false,
+    isSelected: true,
+    canBeSelected: true,
+    description: Em.I18n.t('services.mapreduce2.description')
+  },
+  {
+    serviceName: 'YARN',
+    displayName: 'YARN',
+    isDisabled: false,
+    isSelected: true,
+    canBeSelected: true,
+    description: Em.I18n.t('services.yarn.description')
+  },
+  {
+    serviceName: 'TEZ',
+    displayName: 'TEZ',
+    isDisabled: false,
+    isSelected: true,
+    canBeSelected: true,
+    description: Em.I18n.t('services.tez.description')
+  },
   {
     serviceName: 'NAGIOS',
     displayName: 'Nagios',

+ 5 - 0
ambari-web/app/messages.js

@@ -191,6 +191,9 @@ Em.I18n.translations = {
   'services.zookeeper.description':'ZooKeeper desc',
   'services.hbase.description':'Non-relational distributed database and centralized service for configuration management & synchronization',
   'services.hive.databaseComponent':'Database Server',
+  'services.mapreduce2.description':'Apache Hadoop NextGen MapReduce (client libraries)',
+  'services.yarn.description':'Apache Hadoop NextGen MapReduce (YARN)',
+  'services.tez.description':'Tez is the next generation Hadoop Query Processing framework written on top of YARN',
 
   'services.alerts.head':'You have {0} critical alert notification(s).',
   'services.alerts.OK.timePrefix': 'OK for ',
@@ -445,6 +448,8 @@ Em.I18n.translations = {
   'installer.step10.master.nameNode':'NameNode installed on ',
   'installer.step10.master.secondaryNameNode':'SecondaryNameNode installed on ',
   'installer.step10.master.jobTracker':'JobTracker installed on ',
+  'installer.step10.master.historyServer':'History Server installed on ',
+  'installer.step10.master.resourceManager':'Resource Manager installed on ',
   'installer.step10.master.zooKeeper':'ZooKeeper installed on ',
   'installer.step10.master.hbase':'HBase Master installed on ',
   'installer.step10.master.hiveMetastore':'Hive Metastore installed on ',

+ 1 - 0
ambari-web/app/routes/installer.js

@@ -133,6 +133,7 @@ module.exports = Em.Route.extend({
       var wizardStep1Controller = router.get('wizardStep1Controller');
       var installerController = router.get('installerController');
       installerController.saveStacks(wizardStep1Controller);
+      App.db.setService(undefined);
       installerController.clearInstallOptions();
       router.transitionTo('step2');
     }

+ 12 - 0
ambari-web/app/utils/helper.js

@@ -268,6 +268,18 @@ App.format = {
         return 'TaskTracker';
       case 'MAPREDUCE_CLIENT':
         return 'MapReduce Client';
+      case 'HISTORYSERVER':
+        return 'History Server';
+      case 'NODEMANAGER':
+        return 'Node Manager';
+      case 'RESOURCEMANAGER':
+        return 'Resource Manager';
+      case 'TEZ_CLIENT':
+        return 'Tez Client';
+      case 'MAPREDUCEv2_CLIENT':
+        return 'MapReduce2 Client';
+      case 'YARN_CLIENT':
+        return 'YARN Client';
       case 'JAVA_JCE':
         return 'Java JCE';
       case 'KERBEROS_SERVER':

+ 11 - 4
ambari-web/app/views/wizard/step1_view.js

@@ -23,8 +23,15 @@ App.WizardStep1View = Em.View.extend({
   templateName: require('templates/wizard/step1'),
 
   stacks: function() {
-    return this.get('controller.content.stacks');
-  }.property('controller.content.stacks'),
+    var stacks = [];
+    this.get('controller.content.stacks').forEach(function(stack){
+      stacks.pushObject(Em.Object.create({
+        name: stack.get('name').replace('-', ' '),
+        isSelected: stack.get('isSelected')
+      }));
+    });
+    return stacks;
+  }.property('controller.content.stacks.@each.isSelected'),
 
   stackRadioButton: Ember.Checkbox.extend({
     tagName: 'input',
@@ -35,8 +42,8 @@ App.WizardStep1View = Em.View.extend({
     type: 'radio',
 
     click: function () {
-      this.get('parentView.stacks').setEach('isSelected', false);
-      this.get('parentView.stacks').findProperty('name', this.get('content.name')).set('isSelected', true);
+      this.get('controller.content.stacks').setEach('isSelected', false);
+      this.get('controller.content.stacks').findProperty('name', this.get('content.name').replace(' ', '-')).set('isSelected', true);
     }
   })
 });