Browse Source

AMBARI-989. Show task logs for each host in the Deploy step of the wizard. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1418905 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 years ago
parent
commit
fb75fa8eaa

+ 3 - 0
AMBARI-666-CHANGES.txt

@@ -12,6 +12,9 @@ AMBARI-666 branch (unreleased changes)
 
 
   NEW FEATURES
   NEW FEATURES
 
 
+  AMBARI-989. Show task logs for each host in the Deploy step of the
+  wizard. (yusaku)
+
   AMBARI-976.  Hook HDFS/MapReduce/HBase/Host graphs to backend API
   AMBARI-976.  Hook HDFS/MapReduce/HBase/Host graphs to backend API
   (Srimanth Gunturi via yusaku)
   (Srimanth Gunturi via yusaku)
 
 

File diff suppressed because it is too large
+ 4 - 0
ambari-web/app/assets/data/wizard/deploy/task_log.json


+ 30 - 28
ambari-web/app/controllers/wizard/step9_controller.js

@@ -68,6 +68,7 @@ App.WizardStep9Controller = Em.Controller.extend({
     this.set('status', 'info');
     this.set('status', 'info');
     this.set('progress', '0');
     this.set('progress', '0');
     this.set('isStepCompleted', false);
     this.set('isStepCompleted', false);
+    this.numPolls = 0;
   },
   },
 
 
   loadStep: function () {
   loadStep: function () {
@@ -109,55 +110,56 @@ App.WizardStep9Controller = Em.Controller.extend({
   },
   },
 
 
   displayMessage: function (task) {
   displayMessage: function (task) {
+    var role = App.format.role(task.role);
     console.log("In display message with task command value: " + task.command);
     console.log("In display message with task command value: " + task.command);
     switch (task.command) {
     switch (task.command) {
       case 'INSTALL':
       case 'INSTALL':
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
-            return 'Preparing to install ' + task.role;
+            return 'Preparing to install ' + role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is queued for installation';
+            return role + ' is queued for installation';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
-            return 'Installing ' + task.role;
+            return 'Installing ' + role;
           case 'COMPLETED' :
           case 'COMPLETED' :
-            return 'Successfully installed ' + task.role;
+            return 'Successfully installed ' + role;
           case 'FAILED':
           case 'FAILED':
-            return 'Failed to install ' + task.role;
+            return 'Failed to install ' + role;
         }
         }
       case 'UNINSTALL':
       case 'UNINSTALL':
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
-            return 'Preparing to uninstall ' + task.role;
+            return 'Preparing to uninstall ' + role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is queued for uninstallation';
+            return role + ' is queued for uninstallation';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
-            return 'Uninstalling ' + task.role;
+            return 'Uninstalling ' + role;
           case 'COMPLETED' :
           case 'COMPLETED' :
-            return 'Successfully uninstalled ' + task.role;
+            return 'Successfully uninstalled ' + role;
           case 'FAILED':
           case 'FAILED':
-            return 'Failed to uninstall ' + task.role;
+            return 'Failed to uninstall ' + role;
         }
         }
       case 'START' :
       case 'START' :
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
-            return 'Preparing to start ' + task.role;
+            return 'Preparing to start ' + role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is queued for starting';
+            return role + ' is queued for starting';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
-            return 'Starting ' + task.role;
+            return 'Starting ' + role;
           case 'COMPLETED' :
           case 'COMPLETED' :
-            return task.role + ' started successfully';
+            return role + ' started successfully';
           case 'FAILED':
           case 'FAILED':
-            return task.role + ' failed to start';
+            return role + ' failed to start';
         }
         }
       case 'STOP' :
       case 'STOP' :
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
-            return 'Preparing to stop ' + task.role;
+            return 'Preparing to stop ' + role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is queued for stopping';
+            return role + ' is queued for stopping';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
-            return 'Stopping ' + task.role;
+            return 'Stopping ' + role;
           case 'COMPLETED' :
           case 'COMPLETED' :
             return role + ' stopped successfully';
             return role + ' stopped successfully';
           case 'FAILED':
           case 'FAILED':
@@ -166,28 +168,28 @@ App.WizardStep9Controller = Em.Controller.extend({
       case 'EXECUTE' :
       case 'EXECUTE' :
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
-            return 'Preparing to execute' + task.role;
+            return 'Preparing to execute' + role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is queued for execution';
+            return role + ' is queued for execution';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
-            return 'Execution of ' + task.role + ' in progress';
+            return 'Execution of ' + role + ' in progress';
           case 'COMPLETED' :
           case 'COMPLETED' :
-            return task.role + ' executed successfully';
+            return role + ' executed successfully';
           case 'FAILED':
           case 'FAILED':
-            return task.role + ' failed to execute';
+            return role + ' failed to execute';
         }
         }
       case 'ABORT' :
       case 'ABORT' :
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
-            return 'Preparing to abort ' + task.role;
+            return 'Preparing to abort ' + role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is queued for aborting';
+            return role + ' is queued for aborting';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
-            return 'Aborting ' + task.role;
+            return 'Aborting ' + role;
           case 'COMPLETED' :
           case 'COMPLETED' :
-            return task.role + ' aborted successfully';
+            return role + ' aborted successfully';
           case 'FAILED':
           case 'FAILED':
-            return task.role + ' failed to abort';
+            return role + ' failed to abort';
         }
         }
     }
     }
   },
   },

+ 1 - 51
ambari-web/app/models/protoRelations.js

@@ -68,57 +68,7 @@ App.Service1Component = DS.Model.extend({
   host_name : DS.attr('string'),
   host_name : DS.attr('string'),
 
 
   displayName: function() {
   displayName: function() {
-    switch (this.get('componentName')) {
-      case 'NAMENODE':
-        return 'NameNode';
-      case 'SNAMENODE':
-        return 'SNameNode';
-      case 'DATANODE':
-        return 'DataNode';
-      case 'HDFS_CLIENT':
-        return 'HDFS Client';
-      case 'JOBTRACKER':
-        return 'JobTracker';
-      case 'TASKTRACKER':
-        return 'TaskTracker';
-      case 'MAPREDUCE_CLIENT':
-        return 'MapReduce Client';
-      case 'ZOOKEEPER_SERVER':
-        return 'ZooKeeper Server';
-      case 'ZOOKEEPER_CLIENT':
-        return 'ZooKeeper Client';
-      case 'HIVE_SERVER':
-        return 'Hive Server';
-      case 'HIVE_CLIENT':
-        return 'Hive Client';
-      case 'HIVE_MYSQL':
-        return 'Hive MySQL';
-      case 'HBASE_MASTER':
-        return 'HBase Master';
-      case 'HBASE_REGIONSERVER':
-        return 'RegionServer';
-      case 'HBASE_CLIENT':
-        return 'HBase Client';
-      case 'PIG_CLIENT':
-        return 'Pig Client';
-      case 'SQOOP_CLIENT':
-        return 'Sqoop Client';
-      case 'TEMPLETON_SERVER':
-        return 'Templeton Server';
-      case 'TEMPLETON_CLIENT':
-        return 'Templeton Client';
-      case 'OOZIE_SERVER':
-        return 'Oozie Server';
-      case 'OOZIE_CLIENT':
-        return 'Oozie Client';
-      case 'NAGIOS_SERVER':
-        return 'Nagios Server';
-      case 'GANGLIA_SERVER':
-        return 'Ganglia Collector';
-      case 'GANGLIA_MONITOR':
-        return 'Ganglia Monitor';
-    }
-    return this.get('componentName');
+    return App.format.role(this.get('componentName'));
   }.property('componentName'),
   }.property('componentName'),
 
 
   isMaster: function() {
   isMaster: function() {

+ 15 - 0
ambari-web/app/styles/application.less

@@ -52,6 +52,10 @@ footer {
   padding: 20px 0;
   padding: 20px 0;
 }
 }
 
 
+.modal-body {
+  max-height: 500px;
+}
+
 #top-nav {
 #top-nav {
   .navbar {
   .navbar {
     font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
     font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -294,6 +298,17 @@ h1 {
   }
   }
 }
 }
 
 
+#host-log {
+  .stderr, .stdout {
+    background-color: #f0f0f0;
+    /* max-height: 300px;
+    overflow-y: auto; */
+    border-radius: 4px;
+    padding: 8px;
+  }
+}
+
+
 #serviceConfig {
 #serviceConfig {
   .accordion-heading {
   .accordion-heading {
     background-color: #f0f0f0;
     background-color: #f0f0f0;

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

@@ -46,5 +46,5 @@
 </div>
 </div>
 <div class="btn-area">
 <div class="btn-area">
     <a class="btn pull-left" {{action back href="true"}}>&larr; Back</a>
     <a class="btn pull-left" {{action back href="true"}}>&larr; Back</a>
-    <a class="btn btn-success pull-right" {{action submit target="controller"}}>Next &rarr;</a>
+    <a class="btn btn-success pull-right" {{action submit target="controller"}}>Deploy &rarr;</a>
 </div>
 </div>

+ 15 - 13
ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs

@@ -1,15 +1,17 @@
-<p>Click on the task to see the log: </p><br/>
-<ul>
-  {{#each item in view.roles}}
-  <li>{{item.roleName}}
-    <ul>
-      {{#each state in item.statusArr}}
-      <li>
-        <a {{bindAttr href="state.url"}}>{{state.status}}</a>
-      </li>
-      {{/each}}
-    </ul>
-  </li>
+<p>Click on the task to see the log:</p>
+<div id="host-log">
+  {{#each role in view.roles}}
+    {{#each taskInfo in role.taskInfos}}
+    <div>
+      <a {{action toggleTaskLog taskInfo}}>{{#if taskInfo.isLogHidden}}Show{{else}}Hide{{/if}} {{role.roleName}} {{taskInfo.status}} log</a>
+      <div {{bindAttr class="taskInfo.isLogHidden:hidden"}}>
+        <h5>stderr:</h5>
+        <div class="stderr">{{taskInfo.stderr}}</div>
+        <h5>stdout:</h5>
+        <div class="stdout">{{taskInfo.stdout}}</div>
+      </div>
+    </div>
+    {{/each}}
   {{/each}}
   {{/each}}
-</ul>
+</div>
 
 

+ 106 - 1
ambari-web/app/utils/helper.js

@@ -130,4 +130,109 @@ App.formatUrl = function (urlTemplate, substitutes, testUrl) {
     }
     }
   }
   }
   return formatted;
   return formatted;
-}
+}
+
+App.format = {
+  role: function(role) {
+    switch (role) {
+      case 'ZOOKEEPER_SERVER':
+        return 'ZooKeeper Server';
+      case 'ZOOKEEPER_CLIENT':
+        return 'ZooKeeper Client';
+      case 'NAMENODE':
+        return 'NameNode';
+      case 'NAMENODE_SERVICE_CHECK':
+        return 'NameNode Service Check';
+      case 'DATANODE':
+        return 'DataNode';
+      case 'HDFS_SERVICE_CHECK':
+        return 'HDFS Service Check';
+      case 'SECONDARY_NAMENODE':
+        return 'SNameNode';
+      case 'HDFS_CLIENT':
+        return 'HDFS Client';
+      case 'HBASE_MASTER':
+        return 'HBase Master';
+      case 'HBASE_REGIONSERVER':
+        return 'HBase RegionServer';
+      case 'HBASE_CLIENT':
+        return 'HBase Client';
+      case 'JOBTRACKER':
+        return 'JobTracker';
+      case 'TASKTRACKER':
+        return 'TaskTracker';
+      case 'MAPREDUCE_CLIENT':
+        return 'MapReduce Client';
+      case 'JAVA_JCE':
+        return 'Java JCE';
+      case 'KERBEROS_SERVER':
+        return 'Kerberos Server';
+      case 'KERBEROS_CLIENT':
+        return 'Kerberos Client';
+      case 'KERBEROS_ADMIN_CLIENT':
+        return 'Kerberos Admin Client';
+      case 'HADOOP_CLIENT':
+        return 'Hadoop Client';
+      case 'JOBTRACKER_SERVICE_CHECK':
+        return 'JobTracker Service Check';
+      case 'MAPREDUCE_SERVICE_CHECK':
+        return 'MapReduce Service Check';
+      case 'ZOOKEEPER_SERVICE_CHECK':
+        return 'ZooKeeper Service Check';
+      case 'ZOOKEEPER_QUORUM_SERVICE_CHECK':
+        return 'ZooKeeper Quorum Service Check';
+      case  'HBASE_SERVICE_CHECK':
+        return 'HBase Service Check';
+      case 'MYSQL_SERVER':
+        return 'MySQL Server';
+      case 'HIVE_SERVER':
+        return 'Hive Server';
+      case 'HIVE_CLIENT':
+        return 'Hive Client';
+      case 'HIVE_SERVICE_CHECK':
+        return 'Hive Service Check';
+      case 'HCAT':
+        return 'HCat';
+      case 'HCAT_SERVICE_CHECK':
+        return 'HCat Service Check';
+      case 'OOZIE_CLIENT':
+        return 'Oozie Client';
+      case 'OOZIE_SERVER':
+        return 'Oozie Server';
+      case 'OOZIE_SERVICE_CHECK':
+        return 'Oozie Service Check';
+      case 'PIG':
+        return 'Pig';
+      case 'PIG_SERVICE_CHECK':
+        return 'Pig Service Check';
+      case 'SQOOP':
+        return 'Sqoop';
+      case 'SQOOP_SERVICE_CHECK':
+        return 'Sqoop Service Check';
+      case 'TEMPLETON_CLIENT':
+        return 'Templeton Client';
+      case 'TEMPLETON_SERVER':
+        return 'Templeton Server';
+      case 'TEMPLETON_SERVICE_CHECK':
+        return 'Templeton Service Check';
+      case 'DASHBOARD':
+        return 'Dashboard';
+      case 'DASHBOARD_SERVICE_CHECK':
+        return 'Dashboard Service Check';
+      case 'NAGIOS_SERVER':
+        return 'Nagios Server';
+      case 'GANGLIA_SERVER':
+        return 'Ganglia Server';
+      case 'GANGLIA_MONITOR':
+        return 'Ganglia Monitor';
+      case 'GMOND_SERVICE_CHECK':
+        return 'Gmond Service Check'
+      case 'GMETAD_SERVICE_CHECK':
+        return 'Gmetad Service Check';
+      case 'MONTOR_WEBSERVER':
+        return 'Monitor Webserver'
+      case 'DECOMMISSION_DATANODE':
+        return 'Decommission DataNode';
+    }
+  }
+};

+ 1 - 1
ambari-web/app/views/wizard/step8_view.js

@@ -26,5 +26,5 @@ App.WizardStep8View = Em.View.extend({
   didInsertElement: function () {
   didInsertElement: function () {
     var controller = this.get('controller');
     var controller = this.get('controller');
     controller.loadStep();
     controller.loadStep();
-  }
+  },
 });
 });

+ 38 - 11
ambari-web/app/views/wizard/step9_view.js

@@ -128,24 +128,27 @@ App.HostStatusView = Em.View.extend({
           return this.get('parentView.obj');
           return this.get('parentView.obj');
         }.property('parentView.obj'),
         }.property('parentView.obj'),
 
 
-        logTasks: [],
+        logTasks: [],  // initialized in didInsertElement
+
+        task: null, // set in showTaskLog; contains task info including stdout and stderr
 
 
         roles: function () {
         roles: function () {
           var roleArr = [];
           var roleArr = [];
           var tasks = this.get('logTasks');
           var tasks = this.get('logTasks');
           if (tasks.length) {
           if (tasks.length) {
-            var role = this.get('logTasks').mapProperty('Tasks.role').uniq();
-            role.forEach(function (_role) {
-              var statusArr = [];
+            var _roles = this.get('logTasks').mapProperty('Tasks.role').uniq();
+            _roles.forEach(function (_role) {
+              var taskInfos = [];
               var roleObj = {};
               var roleObj = {};
-              roleObj.roleName = _role;
+              roleObj.roleName = App.format.role(_role);
               tasks.filterProperty('Tasks.role', _role).forEach(function (_task) {
               tasks.filterProperty('Tasks.role', _role).forEach(function (_task) {
-                var statusObj = {};
-                statusObj.status = _task.Tasks.command;
-                statusObj.url = _task.href;
-                statusArr.pushObject(statusObj);
+                var taskInfo = Ember.Object.create();
+                taskInfo.set('status', _task.Tasks.command.toLowerCase());
+                taskInfo.set('url', _task.href);
+                taskInfo.set('isLogHidden', true);
+                taskInfos.pushObject(taskInfo);
               }, this);
               }, this);
-              roleObj.statusArr = statusArr;
+              roleObj.taskInfos = taskInfos;
               roleArr.pushObject(roleObj);
               roleArr.pushObject(roleObj);
             }, this);
             }, this);
           }
           }
@@ -154,10 +157,34 @@ App.HostStatusView = Em.View.extend({
 
 
         didInsertElement: function () {
         didInsertElement: function () {
           console.log('The value of event context is: ' + host.name);
           console.log('The value of event context is: ' + host.name);
-          this.set('logTasks', self.get('controller').getCompletedTasksForHost(event.context));
+          this.set('logTasks', self.get('controller').getCompletedTasksForHost(host));
+        },
+
+        toggleTaskLog: function (event, context) {
+          var taskInfo = event.context;
+          if (taskInfo.get('isLogHidden')) {
+            var url = (App.testMode) ? '/data/wizard/deploy/task_log.json' : taskInfo.url;
+            $.ajax({
+              url: url,
+              dataType: 'text',
+              timeout: 10000,
+              success: function(data) {
+                var task = $.parseJSON(data);
+                taskInfo.set('stdout', task.Tasks.stdout);
+                taskInfo.set('stderr', task.Tasks.stderr);
+                taskInfo.set('isLogHidden', false);
+              },
+              error: function() {
+                alert('Failed to retrieve task log');
+              }
+            });
+          } else {
+            taskInfo.set('isLogHidden', true);
+          }
         }
         }
       })
       })
     });
     });
   }
   }
+
 });
 });
 
 

Some files were not shown because too many files changed in this diff