Преглед изворни кода

AMBARI-1150. Installer Wizard - Retry feature in Deploy step (Step 9) is broken. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1431664 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako пре 12 година
родитељ
комит
7e00fc381d

+ 3 - 0
CHANGES.txt

@@ -654,6 +654,9 @@ AMBARI-666 branch (unreleased changes)
 
   BUG FIXES
 
+  AMBARI-1150. Installer Wizard - Retry feature in Deploy step (Step 9) is
+  broken. (yusaku)
+
   AMBARI-1092. dashboard > Summary > capacity pie chart keeps changing colors.
   (Srimanth Gunturi via yusaku)
 

+ 90 - 40
ambari-web/app/controllers/main/service/info/configs.js

@@ -183,6 +183,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
         self.loadAdvancedConfig(serviceConfigs, advancedConfig);
         self.loadCustomConfig(serviceConfigs);
         var serviceConfig = self.get('serviceConfigs').findProperty('serviceName', self.get('content.serviceName'));
+        self.addHostNamesToGlobalConfig();
         serviceConfig.configs = self.get('globalConfigs').concat(serviceConfigs);
 
         self.renderServiceConfigs(serviceConfig);
@@ -199,6 +200,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     });
   },
 
+
   /**
    * set tagnames for configuration of the *-site.xml
    */
@@ -373,19 +375,21 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     _componentConfig.configs.forEach(function (_serviceConfigProperty) {
       console.log("config", _serviceConfigProperty);
       if (!_serviceConfigProperty) return;
-      if (_serviceConfigProperty.serviceName === this.get('content.serviceName')) {
-        var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
+      var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
+      if (serviceConfigProperty.get('serviceName') === this.get('content.serviceName')) {
         // serviceConfigProperty.serviceConfig = componentConfig;
         if (App.db.getUser().admin) {
           serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
         } else {
           serviceConfigProperty.set('isEditable', false);
         }
-        this.initialValue(serviceConfigProperty);
-        componentConfig.configs.pushObject(serviceConfigProperty);
-        serviceConfigProperty.validate();
+
         console.log("config result", serviceConfigProperty);
+      } else {
+        serviceConfigProperty.set('isVisible', false);
       }
+      componentConfig.configs.pushObject(serviceConfigProperty);
+      serviceConfigProperty.validate();
     }, this);
   },
 
@@ -720,9 +724,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     siteObj.forEach(function (_siteObj) {
       siteProperties[_siteObj.name] = _siteObj.value;
     }, this);
-    if (siteName === 'hdfs-site') {
-      debugger;
-    }
+    //if (siteName === 'hdfs-site') {
+    //debugger;
+    //}
     return {"type": siteName, "tag": tagName, "properties": siteProperties};
   },
 
@@ -841,44 +845,90 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     return (App.testMode) ? testUrl : App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
   },
 
-  initialValue: function (config) {
-    switch (config.name) {
-      case 'namenode_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'NAMENODE').get('host.hostName'));
-        break;
-      case 'snamenode_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'SECONDARY_NAMENODE').get('host.hostName'));
-        break;
-      case 'jobtracker_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'JOBTRACKER').get('host.hostName'));
-        break;
-      case 'hbasemaster_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'HBASE_MASTER').get('host.hostName'));
+  /**
+   * Adds host name of master component to global config;
+   */
+  addHostNamesToGlobalConfig: function () {
+    var serviceName = this.get('content.serviceName');
+    var globalConfigs = this.get('globalConfigs');
+    //namenode_host is required to derive "fs.default.name" a property of core-site
+    var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).configs;
+    var nameNodeHost = this.get('serviceConfigs').findProperty('serviceName', 'HDFS').configs.findProperty('name', 'namenode_host');
+    nameNodeHost.defaultValue = App.Service.find().objectAt(0).get('components').findProperty('componentName', 'NAMENODE').get('host.hostName');
+    globalConfigs.push(nameNodeHost);
+    switch (serviceName) {
+      case 'HDFS':
+        var sNameNodeHost = serviceConfigs.findProperty('name', 'snamenode_host');
+        sNameNodeHost.defaultValue = this.get('content.components').findProperty('componentName', 'SECONDARY_NAMENODE').get('host.hostName');
+        globalConfigs.push(sNameNodeHost);
         break;
-      case 'hivemetastore_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'HIVE_SERVER').get('host.hostName'));
+      case 'MAPREDUCE':
+        var jobTrackerHost = serviceConfigs.findProperty('name', 'jobtracker_host');
+        jobTrackerHost.defaultValue = this.get('content.components').findProperty('componentName', 'JOBTRACKER').get('host.hostName');
+        globalConfigs.push(jobTrackerHost);
         break;
-      case 'hive_ambari_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'HIVE_SERVER').get('host.hostName'));
+      case 'HBASE':
+        var hbaseMasterHost = serviceConfigs.findProperty('name', 'hbasemaster_host');
+        hbaseMasterHost.defaultValue = this.get('content.components').findProperty('componentName', 'HBASE_MASTER').get('host.hostName');
+        globalConfigs.push(hbaseMasterHost);
         break;
-      case 'oozieserver_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'OOZIE_SERVER').get('host.hostName'));
+      case 'HIVE':
+        var hiveMetastoreHost = serviceConfigs.findProperty('name', 'hivemetastore_host');
+        hiveMetastoreHost.defaultValue = this.get('content.components').findProperty('componentName', 'HIVE_SERVER').get('host.hostName');
+        globalConfigs.push(hiveMetastoreHost);
         break;
-      case 'oozie_ambari_host':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'OOZIE_SERVER').get('host.hostName'));
+      case 'OOZIE':
+        var oozieServerHost = serviceConfigs.findProperty('name', 'oozieserver_host');
+        oozieServerHost.defaultValue = this.get('content.components').findProperty('componentName', 'OOZIE_SERVER').get('host.hostName');
+        globalConfigs.push(oozieServerHost);
+        var oozieAmbariHost = serviceConfigs.findProperty('name', 'oozie_ambari_host'); //db hostname
+        oozieAmbariHost.defaultValue = this.get('content.components').findProperty('componentName', 'OOZIE_SERVER').get('host.hostName');
+        globalConfigs.push(oozieAmbariHost);
         break;
-      case 'zookeeperserver_hosts':
-        config.set('id', 'puppet var');
-        config.set('value', this.get('content.components').findProperty('componentName', 'ZOOKEEPER_SERVER').get('host.hostName'));
+      case 'ZOOKEEPER':
+        var zooKeperHost = serviceConfigs.findProperty('name', 'zookeeperserver_hosts');
+        zooKeperHost.defaultValue = this.get('content.components').findProperty('componentName', 'HIVE_SERVER').get('host.hostName');
+        globalConfigs.push(zooKeperHost);
         break;
+      /*
+       case 'namenode_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'NAMENODE').get('host.hostName'));
+       debugger;
+       break;
+       case 'snamenode_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'SECONDARY_NAMENODE').get('host.hostName'));
+       break;
+       case 'jobtracker_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'JOBTRACKER').get('host.hostName'));
+       break;
+       case 'hbasemaster_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'HBASE_MASTER').get('host.hostName'));
+       break;
+       case 'hivemetastore_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'HIVE_SERVER').get('host.hostName'));
+       break;
+       case 'hive_ambari_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'HIVE_SERVER').get('host.hostName'));
+       break;
+       case 'oozieserver_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'OOZIE_SERVER').get('host.hostName'));
+       break;
+       case 'oozie_ambari_host':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'OOZIE_SERVER').get('host.hostName'));
+       break;
+       case 'zookeeperserver_hosts':
+       config.set('id', 'puppet var');
+       config.set('value', this.get('content.components').findProperty('componentName', 'ZOOKEEPER_SERVER').get('host.hostName'));
+       break;
+       */
     }
   }
 

+ 40 - 20
ambari-web/app/controllers/wizard/step9_controller.js

@@ -21,13 +21,16 @@ App.WizardStep9Controller = Em.Controller.extend({
   name: 'wizardStep9Controller',
   hosts: [],
   progress: '0',
+
   isStepCompleted: false,
+
   isSubmitDisabled: function () {
-    return !this.get('isStepCompleted');
-  }.property('isStepCompleted'),
+    // return !this.get('isStepCompleted');
+    return !['STARTED','START FAILED'].contains(this.get('content.cluster.status'));
+  }.property('content.cluster.status'),
 
   mockHostData: require('data/mock/step9_hosts'),
-  mockDataPrefix: '/data/wizard/deploy/slave_warning',
+  mockDataPrefix: '/data/wizard/deploy/5_hosts',
   pollDataCounter: 0,
   polledData: [],
 
@@ -46,24 +49,37 @@ App.WizardStep9Controller = Em.Controller.extend({
   }.property('hosts.@each.status', 'progress'),
 
   showRetry: function () {
-    return this.get('status') == 'failed';
-  }.property('status'),
+    return this.get('content.cluster.status') == 'INSTALL FAILED';
+  }.property('content.cluster.status'),
+
+  // content.cluster.status can be:
+  // PENDING: set upon successful transition from step 1 to step 2
+  // INSTALLED: set upon successful completion of install phase as well as successful invocation of start services API
+  // STARTED: set up on successful completion of start phase
+  // INSTALL FAILED: set up upon encountering a failure in install phase
+  // START FAILED: set upon unsuccessful invocation of start services API and also upon encountering a failure
+  // during start phase
+
+  // content.cluster.isCompleted
+  // set to false upon successful transition from step 1 to step 2
+  // set to true upon successful start of services in this step
+  // note: looks like this is the same thing as checking content.cluster.status == 'STARTED'
 
-  // called by App.WizardStep9View's didInsertElement and "retry" from router.
+
+  // navigateStep is called by App.WizardStep9View's didInsertElement and "retry" from router.
   navigateStep: function () {
-    if (App.testMode) {
+    if (false && App.testMode) {
       // this is for repeatedly testing out installs in test mode
       this.set('content.cluster.status', 'PENDING');
       this.set('content.cluster.isCompleted', false);
     }
+
     if (this.get('content.cluster.isCompleted') === false) {
+      // the cluster has not yet successfully installed and started
       if (this.get('content.cluster.status') === 'INSTALL FAILED') {
         this.loadStep();
         this.loadLogData(this.get('content.cluster.requestId'));
-        this.hosts.setEach('status', 'failed');
-        this.set('progress', '100');
-        this.set('isStepCompleted', true);
-        //this.set('status', 'failed');
+        this.set('content.cluster.isStepCompleted', true);
       } else if (this.get('content.cluster.status') === 'START FAILED') {
         this.loadStep();
         this.loadLogData(this.get('content.cluster.requestId'));
@@ -76,6 +92,7 @@ App.WizardStep9Controller = Em.Controller.extend({
         this.startPolling();
       }
     } else {
+      // the cluster has successfully installed and started
       this.loadStep();
       this.loadLogData(this.get('content.cluster.requestId'));
       this.set('isStepCompleted', true);
@@ -83,7 +100,6 @@ App.WizardStep9Controller = Em.Controller.extend({
 
     }
   },
-
   clearStep: function () {
     this.hosts.clear();
     this.set('status', 'info');
@@ -109,10 +125,10 @@ App.WizardStep9Controller = Em.Controller.extend({
       hosts.add(obj);
       console.log("TRACE: host name is: " + hostInfo[index].name);
     }
-    // return hosts;
     return hosts.filterProperty('bootStatus', 'REGISTERED');
   },
 
+  // sets this.hosts, where each element corresponds to a status and progress info on a host
   renderHosts: function (hostsInfo) {
     hostsInfo.forEach(function (_hostInfo) {
       var hostInfo = App.HostInfo.create({
@@ -331,8 +347,7 @@ App.WizardStep9Controller = Em.Controller.extend({
   },
 
   isStepFailed: function (polledData) {
-    var self = this;
-    var result = false;
+    var failed = false;
     polledData.forEach(function (_polledData) {
       var successFactor = this.getSuccessFactor(_polledData.Tasks.role);
       console.log("Step9: isStepFailed sf value: " + successFactor);
@@ -342,10 +357,10 @@ App.WizardStep9Controller = Em.Controller.extend({
       var actionsTimedOut = actionsPerRole.filterProperty('Tasks.status', 'TIMEDOUT');
       if ((((actionsFailed.length + actionsAborted.length + actionsTimedOut.length) / actionsPerRole.length) * 100) > (100 - successFactor)) {
         console.log('TRACE: Entering success factor and result is failed');
-        result = true;
+        failed = true;
       }
     }, this);
-    return result;
+    return failed;
   },
 
   getFailedHostsForFailedRoles: function (polledData) {
@@ -427,6 +442,7 @@ App.WizardStep9Controller = Em.Controller.extend({
           this.setHostsStatus(this.getFailedHostsForFailedRoles(polledData), 'failed');
           App.router.get(this.get('content.controllerName')).saveClusterStatus(clusterStatus);
           this.set('isStepCompleted', true);
+          // return false;
         } else {
           clusterStatus.status = 'INSTALLED';
           this.set('progress', '34');
@@ -493,7 +509,7 @@ App.WizardStep9Controller = Em.Controller.extend({
       var actionsPerHost = tasksData.filterProperty('Tasks.host_name', _host.name); // retrieved from polled Data
       if (actionsPerHost.length === 0) {
         _host.set('message', this.t('installer.step9.host.status.nothingToInstall'));
-        console.log("Error: No task is hosted on the host");
+        console.log("INFO: No task is hosted on the host");
       }
       if (actionsPerHost !== null && actionsPerHost !== undefined && actionsPerHost.length !== 0) {
         this.setLogTasksStatePerHost(actionsPerHost, _host);
@@ -526,7 +542,7 @@ App.WizardStep9Controller = Em.Controller.extend({
 
   POLL_INTERVAL: 4000,
 
-  loadLogData:function(requestId){
+  loadLogData: function(requestId) {
     var url = this.getUrl(requestId);
     var requestsId = App.db.getCluster().oldRequestsId;
     if (App.testMode) {
@@ -549,6 +565,8 @@ App.WizardStep9Controller = Em.Controller.extend({
       this.getLogsByRequest(url, false);
     }, this);
   },
+
+  // polling: whether to continue polling for status or not
   getLogsByRequest: function(url, polling){
     var self = this;
     $.ajax({
@@ -561,7 +579,7 @@ App.WizardStep9Controller = Em.Controller.extend({
         console.log("TRACE: In success function for the GET logs data");
         console.log("TRACE: STep9 -> The value is: ", jQuery.parseJSON(data));
         var result = self.parseHostInfo(jQuery.parseJSON(data));
-        if(!polling){
+        if (!polling) {
           return;
         }
         if (result !== true) {
@@ -588,12 +606,14 @@ App.WizardStep9Controller = Em.Controller.extend({
       }
     );
   },
+
   doPolling: function () {
     var url = this.getUrl();
 
     if (App.testMode) {
       this.numPolls++;
       url = this.get('mockDataPrefix') + '/poll_' + this.get('numPolls') + '.json';
+      debugger;
     }
     this.getLogsByRequest(url, true);
   },

+ 3 - 3
ambari-web/app/messages.js

@@ -134,9 +134,9 @@ Em.I18n.translations = {
 
   'installer.step9.header':'Install, Start and Test',
   'installer.step9.body':'Please wait while the selected services are installed, started, and tested on your new cluster.',
-  'installer.step9.status.success':'Successfully installed the cluster.',
-  'installer.step9.status.warning':'Installed the cluster with some warnings.',
-  'installer.step9.status.failed':'Failed to install the cluster.',
+  'installer.step9.status.success':'Successfully installed and started the cluster.',
+  'installer.step9.status.warning':'Installed and started the cluster with some warnings.',
+  'installer.step9.status.failed':'Failed to install/start the cluster.',
   'installer.step9.host.status.success':'Success',
   'installer.step9.host.status.warning':'Warnings encountered',
   'installer.step9.host.status.failed':'Failures encountered',

+ 3 - 2
ambari-web/app/routes/installer.js

@@ -270,9 +270,10 @@ module.exports = Em.Route.extend({
     retry: function (router) {
       var installerController = router.get('installerController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
-      if (!wizardStep9Controller.get('isSubmitDisabled')) {
+      if (wizardStep9Controller.get('showRetry')) {
         if (wizardStep9Controller.get('content.cluster.status') !== 'START FAILED') {
-          installerController.installServices(true);
+          var isRetry = true;
+          installerController.installServices(isRetry);
           installerController.setInfoForStep9();
         } else {
           wizardStep9Controller.set('content.cluster.isCompleted', false);

+ 1 - 1
ambari-web/app/templates/wizard/step9.hbs

@@ -40,7 +40,7 @@
     <div class="box-header">
       <div class="pull-left">
         {{#if controller.showRetry}}
-        <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
+        <a class="btn btn-primary"
            href="#" {{action retry}}><i class="icon-repeat icon-white"></i>
           Retry
         </a>