From 444f081e2fce75166c7a9735bf8842bc1b754056 Mon Sep 17 00:00:00 2001
From: Todd Lipcon <todd@lipcon.org>
Date: Wed, 24 Feb 2010 21:56:45 -0800
Subject: [PATCH] Improve markup and add Cloudera styling to Web UIs

This adds a favicon and a number of HTML/CSS improvements to make the
pages more space-efficient and easy on the eyes.

This may be an incompatible change for users who are scraping the HTML
output of the web UIs. Those users are encouraged to access the data
programmatically rather than through scraping.

The non-Cloudera-specific improvements will be contributed upstream
as HDFS-1013 and MAPREDUCE-1544.
---
 src/core/org/apache/hadoop/util/ServletUtil.java   |    3 +-
 .../hadoop/hdfs/server/namenode/JspHelper.java     |   25 ++++------
 src/mapred/org/apache/hadoop/mapred/JSPUtil.java   |   36 ++++++++------
 src/webapps/datanode/browseBlock.jsp               |    2 +
 src/webapps/datanode/browseDirectory.jsp           |   18 +++----
 src/webapps/datanode/tail.jsp                      |    2 +
 src/webapps/hdfs/dfshealth.jsp                     |    1 +
 src/webapps/hdfs/dfsnodelist.jsp                   |    1 +
 src/webapps/job/analysejobhistory.jsp              |   32 ++++++++++---
 src/webapps/job/jobblacklistedtrackers.jsp         |    5 ++-
 src/webapps/job/jobconf.jsp                        |    6 ++-
 src/webapps/job/jobconf_history.jsp                |    6 ++-
 src/webapps/job/jobdetails.jsp                     |    1 +
 src/webapps/job/jobdetailshistory.jsp              |   23 ++++++---
 src/webapps/job/jobfailures.jsp                    |    9 +++-
 src/webapps/job/jobhistory.jsp                     |   13 +++--
 src/webapps/job/jobqueue_details.jsp               |    1 +
 src/webapps/job/jobtasks.jsp                       |   10 +++-
 src/webapps/job/jobtaskshistory.jsp                |   13 ++++-
 src/webapps/job/jobtracker.jsp                     |    1 +
 src/webapps/job/machines.jsp                       |   24 +++++----
 src/webapps/job/taskdetails.jsp                    |   15 ++++--
 src/webapps/job/taskdetailshistory.jsp             |   17 +++++--
 src/webapps/job/taskstats.jsp                      |    2 +
 src/webapps/static/hadoop.css                      |   51 ++++++++++++++++++++
 src/webapps/static/images/favicon.ico              |  Bin 0 -> 1150 bytes
 src/webapps/static/jobconf.xsl                     |    6 ++-
 src/webapps/task/tasktracker.jsp                   |    6 ++-
 28 files changed, 234 insertions(+), 95 deletions(-)
 create mode 100644 src/webapps/static/images/favicon.ico

diff --git a/src/core/org/apache/hadoop/util/ServletUtil.java b/src/core/org/apache/hadoop/util/ServletUtil.java
index d755b8e..0a5eedf 100644
--- a/src/core/org/apache/hadoop/util/ServletUtil.java
+++ b/src/core/org/apache/hadoop/util/ServletUtil.java
@@ -52,7 +52,8 @@ public class ServletUtil {
   }
 
   public static final String HTML_TAIL = "<hr />\n"
-    + "<a href='http://hadoop.apache.org/core'>Hadoop</a>, " 
+    + "<a href=\"http://www.cloudera.com/hadoop/\">Cloudera's Distribution"
+    + " of Hadoop</a>, " + 
     + Calendar.getInstance().get(Calendar.YEAR) + ".\n"
     + "</body></html>";
   
diff --git a/src/hdfs/org/apache/hadoop/hdfs/server/namenode/JspHelper.java b/src/hdfs/org/apache/hadoop/hdfs/server/namenode/JspHelper.java
index 42b4f5b..11f989a 100644
--- a/src/hdfs/org/apache/hadoop/hdfs/server/namenode/JspHelper.java
+++ b/src/hdfs/org/apache/hadoop/hdfs/server/namenode/JspHelper.java
@@ -161,32 +161,25 @@ public class JspHelper {
       fsn.DFSNodesStatus(live, dead);
   }
   public void addTableHeader(JspWriter out) throws IOException {
-    out.print("<table border=\"1\""+
-              " cellpadding=\"2\" cellspacing=\"2\">");
-    out.print("<tbody>");
+    out.print("<table class=\"nnbrowse datatable\">\n");
   }
-  public void addTableRow(JspWriter out, String[] columns) throws IOException {
+
+  public void addTableHeadingRow(JspWriter out, String[] columns) throws IOException {
     out.print("<tr>");
-    for (int i = 0; i < columns.length; i++) {
-      out.print("<td style=\"vertical-align: top;\"><B>"+columns[i]+"</B><br></td>");
+    for (String col : columns) {
+      out.print("<th>" + col + "</th>\n");
     }
     out.print("</tr>");
   }
-  public void addTableRow(JspWriter out, String[] columns, int row) throws IOException {
+  public void addTableRow(JspWriter out, String[] columns) throws IOException {
     out.print("<tr>");
-      
-    for (int i = 0; i < columns.length; i++) {
-      if (row/2*2 == row) {//even
-        out.print("<td style=\"vertical-align: top;background-color:LightGrey;\"><B>"+columns[i]+"</B><br></td>");
-      } else {
-        out.print("<td style=\"vertical-align: top;background-color:LightBlue;\"><B>"+columns[i]+"</B><br></td>");
-          
-      }
+    for (String col : columns) {
+      out.print("<td>" + col + "</td>\n");
     }
     out.print("</tr>");
   }
   public void addTableFooter(JspWriter out) throws IOException {
-    out.print("</tbody></table>");
+    out.print("</table>");
   }
 
   public String getSafeModeText() {
diff --git a/src/mapred/org/apache/hadoop/mapred/JSPUtil.java b/src/mapred/org/apache/hadoop/mapred/JSPUtil.java
index 7a86ac4..f9ef98d 100644
--- a/src/mapred/org/apache/hadoop/mapred/JSPUtil.java
+++ b/src/mapred/org/apache/hadoop/mapred/JSPUtil.java
@@ -88,11 +88,13 @@ class JSPUtil {
                                       PRIVATE_ACTIONS_KEY, false);
     StringBuffer sb = new StringBuffer();
     
-    sb.append("<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\">\n");
-
+    sb.append("<table class=\"datatable\">\n");
     if (jobs.size() > 0) {
       if (isModifiable) {
         sb.append("<form action=\"/jobtracker.jsp\" onsubmit=\"return confirmAction();\" method=\"POST\">");
+      }
+      sb.append("<thead>");
+      if (isModifiable) {
         sb.append("<tr>");
         sb.append("<td><input type=\"Button\" onclick=\"selectAll()\" " +
         		"value=\"Select All\" id=\"checkEm\"></td>");
@@ -114,22 +116,25 @@ class JSPUtil {
         sb.append("</nobr></td>");
         sb.append("<td colspan=\"10\">&nbsp;</td>");
         sb.append("</tr>");
-        sb.append("<td>&nbsp;</td>");
-      } else {
-        sb.append("<tr>");
       }
+      sb.append("<tr>");
 
-      sb.append("<td><b>Jobid</b></td><td><b>Priority" +
-      		"</b></td><td><b>User</b></td>");
-      sb.append("<td><b>Name</b></td>");
-      sb.append("<td><b>Map % Complete</b></td>");
-      sb.append("<td><b>Map Total</b></td>");
-      sb.append("<td><b>Maps Completed</b></td>");
-      sb.append("<td><b>Reduce % Complete</b></td>");
-      sb.append("<td><b>Reduce Total</b></td>");
-      sb.append("<td><b>Reduces Completed</b></td>");
-      sb.append("<td><b>Job Scheduling Information</b></td>");
+      if (isModifiable) {
+        sb.append("<td>&nbsp;</td>");
+      }
+      sb.append("<th>");
+      sb.append("<b>Jobid</b></th><th><b>Priority" +
+      		"</b></th><th><b>User</b></th>");
+      sb.append("<th><b>Name</b></th>");
+      sb.append("<th><b>Map % Complete</b></th>");
+      sb.append("<th><b>Map Total</b></th>");
+      sb.append("<th><b>Maps Completed</b></th>");
+      sb.append("<th><b>Reduce % Complete</b></th>");
+      sb.append("<th><b>Reduce Total</b></th>");
+      sb.append("<th><b>Reduces Completed</b></th>");
+      sb.append("<th><b>Job Scheduling Information</b></th>");
       sb.append("</tr>\n");
+      sb.append("</thead><tbody>");
       for (Iterator<JobInProgress> it = jobs.iterator(); it.hasNext(); ++rowId) {
         JobInProgress job = it.next();
         JobProfile profile = job.getProfile();
@@ -169,6 +174,7 @@ class JSPUtil {
             + "</td><td>" + schedulingInfo
             + "</td></tr>\n");
       }
+      sb.append("</tbody>");
       if (isModifiable) {
         sb.append("</form>\n");
       }
diff --git a/src/webapps/datanode/browseBlock.jsp b/src/webapps/datanode/browseBlock.jsp
index 127b096..8ee469d 100644
--- a/src/webapps/datanode/browseBlock.jsp
+++ b/src/webapps/datanode/browseBlock.jsp
@@ -367,6 +367,8 @@
 <html>
 <head>
 <%JspHelper.createTitle(out, request, request.getParameter("filename")); %>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 </head>
 <body onload="document.goto.dir.focus()">
 <% 
diff --git a/src/webapps/datanode/browseDirectory.jsp b/src/webapps/datanode/browseDirectory.jsp
index e577dc5..0917149 100644
--- a/src/webapps/datanode/browseDirectory.jsp
+++ b/src/webapps/datanode/browseDirectory.jsp
@@ -99,8 +99,9 @@
       }
       else {
         jspHelper.addTableHeader(out);
-        int row=0;
-        jspHelper.addTableRow(out, headings, row++);
+        out.print("<thead>\n");
+        jspHelper.addTableHeadingRow(out, headings);
+        out.print("</thead><tbody>\n");
         String cols [] = new String[headings.length];
         for (int i = 0; i < files.length; i++) {
           //Get the location of the first block of the file
@@ -125,8 +126,9 @@
           cols[6] = files[i].getPermission().toString();
           cols[7] = files[i].getOwner();
           cols[8] = files[i].getGroup();
-          jspHelper.addTableRow(out, cols, row++);
+          jspHelper.addTableRow(out, cols);
         }
+        out.print("</tbody>\n");
         jspHelper.addTableFooter(out);
       }
     } 
@@ -141,14 +143,8 @@
 
 <html>
 <head>
-<style type=text/css>
-<!--
-body 
-  {
-  font-face:sanserif;
-  }
--->
-</style>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 <%JspHelper.createTitle(out, request, request.getParameter("dir")); %>
 </head>
 
diff --git a/src/webapps/datanode/tail.jsp b/src/webapps/datanode/tail.jsp
index 8d50b35..63d6a14 100644
--- a/src/webapps/datanode/tail.jsp
+++ b/src/webapps/datanode/tail.jsp
@@ -110,6 +110,8 @@
 <html>
 <head>
 <%JspHelper.createTitle(out, request, request.getParameter("filename")); %>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 </head>
 <body>
 <form action="/tail.jsp" method="GET">
diff --git a/src/webapps/hdfs/dfshealth.jsp b/src/webapps/hdfs/dfshealth.jsp
index 58fb07d..247ba71 100644
--- a/src/webapps/hdfs/dfshealth.jsp
+++ b/src/webapps/hdfs/dfshealth.jsp
@@ -243,6 +243,7 @@
 <html>
 
 <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 <title>Hadoop NameNode <%=namenodeLabel%></title>
     
 <body>
diff --git a/src/webapps/hdfs/dfsnodelist.jsp b/src/webapps/hdfs/dfsnodelist.jsp
index a588b03..a94a024 100644
--- a/src/webapps/hdfs/dfsnodelist.jsp
+++ b/src/webapps/hdfs/dfsnodelist.jsp
@@ -306,6 +306,7 @@ String namenodeLabel = nn.getNameNodeAddress().getHostName() + ":" + nn.getNameN
 <html>
 
 <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 <title>Hadoop NameNode <%=namenodeLabel%></title>
   
 <body>
diff --git a/src/webapps/job/analysejobhistory.jsp b/src/webapps/job/analysejobhistory.jsp
index f19436c..978b529 100644
--- a/src/webapps/job/analysejobhistory.jsp
+++ b/src/webapps/job/analysejobhistory.jsp
@@ -15,7 +15,7 @@
 <%!	private static SimpleDateFormat dateFormat 
                               = new SimpleDateFormat("d/MM HH:mm:ss") ; 
 %>
-<html><body>
+<html>
 <%
   String jobid = request.getParameter("jobid");
   String logFile = request.getParameter("logFile");
@@ -27,6 +27,13 @@
   }
   JobInfo job = (JobInfo)request.getSession().getAttribute("job");
 %>
+<head>
+  <title>Analyze Job - Hadoop Job <%=jobid %></title>
+  <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+  <link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
+
+<body>
 <h2>Hadoop Job <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=encodedLogFileName%>"><%=jobid %> </a></h2>
 <b>User : </b> <%=job.get(Keys.USER) %><br/> 
 <b>JobName : </b> <%=job.get(Keys.JOBNAME) %><br/> 
@@ -106,8 +113,11 @@
 <h3>Average time taken by Map tasks: 
 <%=StringUtils.formatTimeDiff(avgMapTime, 0) %></h3>
 <h3>Worse performing map tasks</h3>
-<table border="2" cellpadding="5" cellspacing="2">
-<tr><td>Task Id</td><td>Time taken</td></tr>
+<table class="jobtasks datatable">
+<thead>
+<tr><th>Task Id</th><th>Time taken</th></tr>
+</thead>
+<tbody>
 <%
   for (int i=0;i<showTasks && i<mapTasks.length; i++) {
 %>
@@ -119,6 +129,7 @@
 <%
   }
 %>
+</tbody>
 </table>
 <%  
   Comparator<JobHistory.Task> cFinishMapRed = 
@@ -155,8 +166,10 @@ finished at (relative to the Job launch time):
 <h3>Average time taken by Shuffle: 
 <%=StringUtils.formatTimeDiff(avgShuffleTime, 0) %></h3>
 <h3>Worse performing Shuffle(s)</h3>
-<table border="2" cellpadding="5" cellspacing="2">
-<tr><td>Task Id</td><td>Time taken</td></tr>
+<table class="jobtasks datatable">
+<thead>
+<tr><th>Task Id</th><th>Time taken</th></tr>
+</thead><tbody>
 <%
   for (int i=0;i<showTasks && i<reduceTasks.length; i++) {
 %>
@@ -173,6 +186,7 @@ finished at (relative to the Job launch time):
 <%
   }
 %>
+</tbody>
 </table>
 <%  
   Comparator<JobHistory.Task> cFinishShuffle = 
@@ -218,8 +232,11 @@ finished at (relative to the Job launch time):
 <h3>Average time taken by Reduce tasks: 
 <%=StringUtils.formatTimeDiff(avgReduceTime, 0) %></h3>
 <h3>Worse performing reduce tasks</h3>
-<table border="2" cellpadding="5" cellspacing="2">
-<tr><td>Task Id</td><td>Time taken</td></tr>
+<table class="jobtasks datatable">
+<thead>
+<tr><th>Task Id</th><th>Time taken</th></tr>
+</thead>
+<tbody>
 <%
   for (int i=0;i<showTasks && i<reduceTasks.length; i++) {
 %>
@@ -233,6 +250,7 @@ finished at (relative to the Job launch time):
 <%
   }
 %>
+</tbody>
 </table>
 <%  
   Arrays.sort(reduceTasks, cFinishMapRed);
diff --git a/src/webapps/job/jobblacklistedtrackers.jsp b/src/webapps/job/jobblacklistedtrackers.jsp
index 6e9caa7..67dec16 100644
--- a/src/webapps/job/jobblacklistedtrackers.jsp
+++ b/src/webapps/job/jobblacklistedtrackers.jsp
@@ -44,8 +44,11 @@
     }
 %>
 
-<html>
+<html><head>
 <title>Hadoop <%=jobId%>'s black-listed tasktrackers</title>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h1>Hadoop <a href="jobdetails.jsp?jobid=<%=jobId%>"><%=jobId%></a> - 
 Black-listed task-trackers</h1>
diff --git a/src/webapps/job/jobconf.jsp b/src/webapps/job/jobconf.jsp
index d7e439d..bc7f667 100644
--- a/src/webapps/job/jobconf.jsp
+++ b/src/webapps/job/jobconf.jsp
@@ -19,9 +19,11 @@
 %>
   
 <html>
-
+<head>
 <title>Job Configuration: JobId - <%= jobId %></title>
-
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h2>Job Configuration: JobId - <%= jobId %></h2><br>
 
diff --git a/src/webapps/job/jobconf_history.jsp b/src/webapps/job/jobconf_history.jsp
index 50eaf7a..9422beb 100644
--- a/src/webapps/job/jobconf_history.jsp
+++ b/src/webapps/job/jobconf_history.jsp
@@ -20,9 +20,11 @@
 %>
   
 <html>
-
+<head>
 <title>Job Configuration: JobId - <%= jobId %></title>
-
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h2>Job Configuration: JobId - <%= jobId %></h2><br>
 
diff --git a/src/webapps/job/jobdetails.jsp b/src/webapps/job/jobdetails.jsp
index 5546a4a..bca8c56 100644
--- a/src/webapps/job/jobdetails.jsp
+++ b/src/webapps/job/jobdetails.jsp
@@ -191,6 +191,7 @@
   %>
 <title>Hadoop <%=jobId%> on <%=trackerName%></title>
 <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 </head>
 <body>
 <h1>Hadoop <%=jobId%> on <a href="jobtracker.jsp"><%=trackerName%></a></h1>
diff --git a/src/webapps/job/jobdetailshistory.jsp b/src/webapps/job/jobdetailshistory.jsp
index ae4c97e..00bbbf6 100644
--- a/src/webapps/job/jobdetailshistory.jsp
+++ b/src/webapps/job/jobdetailshistory.jsp
@@ -26,7 +26,16 @@
     JobInfo job = (JobInfo)request.getSession().getAttribute("job");
     FileSystem fs = (FileSystem)request.getSession().getAttribute("fs");
 %>
-<html><body>
+<html>
+<head>
+<title>
+Hadoop Job <%=jobid %> on History Viewer
+</title>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
+<body>
+
 <h2>Hadoop Job <%=jobid %> on <a href="jobhistory.jsp">History Viewer</a></h2>
 
 <b>User: </b> <%=job.get(Keys.USER) %><br/> 
@@ -133,12 +142,12 @@
 <b><a href="analysejobhistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>">Analyse This Job</a></b> 
 <hr/>
 <center>
-<table border="2" cellpadding="5" cellspacing="2">
+<table>
 <tr>
-<td>Kind</td><td>Total Tasks(successful+failed+killed)</td><td>Successful tasks</td><td>Failed tasks</td><td>Killed tasks</td><td>Start Time</td><td>Finish Time</td>
+<th>Kind</th><th>Total Tasks(successful+failed+killed)</th><th>Successful tasks</th><th>Failed tasks</th><th>Killed tasks</th><th>Start Time</th><th>Finish Time</th>
 </tr>
 <tr>
-<td>Setup</td>
+<th>Setup</th>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.SETUP.name() %>&status=all">
         <%=totalSetups%></a></td>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.SETUP.name() %>&status=<%=Values.SUCCESS %>">
@@ -151,7 +160,7 @@
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, setupFinished, setupStarted) %></td>
 </tr>
 <tr>
-<td>Map</td>
+<th>Map</th>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.MAP.name() %>&status=all">
         <%=totalMaps %></a></td>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.MAP.name() %>&status=<%=Values.SUCCESS %>">
@@ -164,7 +173,7 @@
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, mapFinished, mapStarted) %></td>
 </tr>
 <tr>
-<td>Reduce</td>
+<th>Reduce</th>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.REDUCE.name() %>&status=all">
         <%=totalReduces%></a></td>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.REDUCE.name() %>&status=<%=Values.SUCCESS %>">
@@ -177,7 +186,7 @@
     <td><%=StringUtils.getFormattedTimeWithDiff(dateFormat, reduceFinished, reduceStarted) %></td>
 </tr>
 <tr>
-<td>Cleanup</td>
+<th>Cleanup</th>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.CLEANUP.name() %>&status=all">
         <%=totalCleanups%></a></td>
     <td><a href="jobtaskshistory.jsp?jobid=<%=jobid %>&logFile=<%=encodedLogFileName%>&taskType=<%=Values.CLEANUP.name() %>&status=<%=Values.SUCCESS %>">
diff --git a/src/webapps/job/jobfailures.jsp b/src/webapps/job/jobfailures.jsp
index d2ea20a..1ed4f7c 100644
--- a/src/webapps/job/jobfailures.jsp
+++ b/src/webapps/job/jobfailures.jsp
@@ -121,9 +121,11 @@
       return;
     }
     	
-    out.print("<table border=2 cellpadding=\"5\" cellspacing=\"2\">");
+    out.print("<table class=\"jobtasks datatable\">");
+    out.print("<thead>");
     out.print("<tr><th>Attempt</th><th>Task</th><th>Machine</th><th>State</th>" +
               "<th>Error</th><th>Logs</th></tr>\n");
+    out.print("</thead><tbody>\n");
     if (includeMap) {
       TaskInProgress[] tips = job.getMapTasks();
       for(int i=0; i < tips.length; ++i) {
@@ -136,6 +138,7 @@
         printFailedAttempts(out, tracker, jobId, tips[i], state);
       }
     }
+    out.print("</tbody>\n");
     out.print("</table>\n");
   }
 %>
@@ -152,7 +155,11 @@
 %>
 
 <html>
+<head>
 <title>Hadoop <%=jobId%> failures on <%=trackerName%></title>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h1>Hadoop <a href="jobdetails.jsp?jobid=<%=jobId%>"><%=jobId%></a>
 failures on <a href="jobtracker.jsp"><%=trackerName%></a></h1>
diff --git a/src/webapps/job/jobhistory.jsp b/src/webapps/job/jobhistory.jsp
index a399a79..4dc9d22 100644
--- a/src/webapps/job/jobhistory.jsp
+++ b/src/webapps/job/jobhistory.jsp
@@ -35,9 +35,9 @@ window.location.href = url;
 }
 //-->
 </script>
-<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
 <title><%= trackerName %> Hadoop Map/Reduce History Viewer</title>
 <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 </head>
 <body>
 <h1> <a href="jobtracker.jsp"><%= trackerName %></a> Hadoop Map/Reduce 
@@ -199,12 +199,14 @@ window.location.href = url;
     // print the navigation info (top)
     printNavigation(pageno, size, maxPageNo, search, out);
 
-    out.print("<table align=center border=2 cellpadding=\"5\" cellspacing=\"2\">");
+    out.print("<table class=\"datatable\">");
+    out.print("<thead>\n");
     out.print("<tr>");
-    out.print("<td>Job tracker Host Name</td>" +
-              "<td>Job tracker Start time</td>" +
-              "<td>Job Id</td><td>Name</td><td>User</td>") ; 
+    out.print("<th>Job tracker Host Name</th>" +
+              "<th>Job tracker Start time</th>" +
+              "<th>Job Id</th><th>Name</th><th>User</th>") ; 
     out.print("</tr>"); 
+    out.print("</thead><tbody>\n");
     
     Set<String> displayedJobs = new HashSet<String>();
     for (int i = start - 1; i < start + length - 1; ++i) {
@@ -241,6 +243,7 @@ window.location.href = url;
 </center> 
 <%
     } // end while trackers 
+    out.print("</tbody>");
     out.print("</table>");
 
     // show the navigation info (bottom)
diff --git a/src/webapps/job/jobqueue_details.jsp b/src/webapps/job/jobqueue_details.jsp
index 6f5e9b5..4ca3a14 100644
--- a/src/webapps/job/jobqueue_details.jsp
+++ b/src/webapps/job/jobqueue_details.jsp
@@ -26,6 +26,7 @@ private static final long serialVersionUID = 526456771152222127L;
 <head>
 <title>Queue details for <%=queueName!=null?queueName:""%> </title>
 <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 <script type="text/javascript" src="/static/jobtracker.js"></script>
 </head>
 <body>
diff --git a/src/webapps/job/jobtasks.jsp b/src/webapps/job/jobtasks.jsp
index 3d4457c..314ef8c 100644
--- a/src/webapps/job/jobtasks.jsp
+++ b/src/webapps/job/jobtasks.jsp
@@ -49,6 +49,7 @@
   <head>
     <title>Hadoop <%=type%> task list for <%=jobid%> on <%=trackerName%></title>
     <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+    <link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
   </head>
 <body>
 <h1>Hadoop <%=type%> task list for 
@@ -83,9 +84,11 @@
     out.print("<h2>" + Character.toUpperCase(state.charAt(0)) 
               + state.substring(1).toLowerCase() + " Tasks</h2>");
     out.print("<center>");
-    out.print("<table border=2 cellpadding=\"5\" cellspacing=\"2\">");
-    out.print("<tr><td align=\"center\">Task</td><td>Complete</td><td>Status</td>" +
-              "<td>Start Time</td><td>Finish Time</td><td>Errors</td><td>Counters</td></tr>");
+    out.print("<table class=\"jobtasks datatable\">");
+    out.print("<thead>");
+    out.print("<tr><th align=\"center\">Task</th><th>Complete</th><th>Status</th>" +
+              "<th>Start Time</th><th>Finish Time</th><th>Errors</th><th>Counters</th></tr>");
+    out.print("</thead><tbody>");
     if (end_index > report_len){
         end_index = report_len;
     }
@@ -112,6 +115,7 @@
              "\">" + report.getCounters().size() +
              "</a></td></tr>");
     }
+    out.print("</tbody>");
     out.print("</table>");
     out.print("</center>");
   }
diff --git a/src/webapps/job/jobtaskshistory.jsp b/src/webapps/job/jobtaskshistory.jsp
index 3091db6..94a5474 100644
--- a/src/webapps/job/jobtaskshistory.jsp
+++ b/src/webapps/job/jobtaskshistory.jsp
@@ -29,11 +29,19 @@
   Map<String, JobHistory.Task> tasks = job.getAllTasks(); 
 %>
 <html>
+<head>
+  <title><%=taskStatus%> <%=taskType %> task list for <%=jobid %></title>
+  <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+  <link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h2><%=taskStatus%> <%=taskType %> task list for <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=encodedLogFileName%>"><%=jobid %> </a></h2>
 <center>
-<table border="2" cellpadding="5" cellspacing="2">
-<tr><td>Task Id</td><td>Start Time</td><td>Finish Time<br/></td><td>Error</td></tr>
+<table class="jobtasks datatable">
+<thead>
+<tr><th>Task Id</th><th>Start Time</th><th>Finish Time<br/></th><th>Error</th></tr>
+</thead>
+<tbody>
 <%
   for (JobHistory.Task task : tasks.values()) {
     if (taskType.equals(task.get(Keys.TASK_TYPE))){
@@ -47,6 +55,7 @@
     }
   }
 %>
+</tbody>
 </table>
 <%!
   private void printTask(String jobid, String logFile,
diff --git a/src/webapps/job/jobtracker.jsp b/src/webapps/job/jobtracker.jsp
index e523b89..875e9db 100644
--- a/src/webapps/job/jobtracker.jsp
+++ b/src/webapps/job/jobtracker.jsp
@@ -63,6 +63,7 @@
 <head>
 <title><%= trackerName %> Hadoop Map/Reduce Administration</title>
 <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
 <script type="text/javascript" src="/static/jobtracker.js"></script>
 </head>
 <body>
diff --git a/src/webapps/job/machines.jsp b/src/webapps/job/machines.jsp
index 2c5deff..52bea68 100644
--- a/src/webapps/job/machines.jsp
+++ b/src/webapps/job/machines.jsp
@@ -30,14 +30,15 @@
       out.print("There are currently no known " + type + " Task Trackers.");
     } else {
       out.print("<center>\n");
-      out.print("<table border=\"2\" cellpadding=\"5\" cellspacing=\"2\">\n");
-      out.print("<tr><td align=\"center\" colspan=\"6\"><b>Task Trackers</b></td></tr>\n");
-      out.print("<tr><td><b>Name</b></td><td><b>Host</b></td>" +
-                "<td><b># running tasks</b></td>" +
-                "<td><b>Max Map Tasks</b></td>" +
-                "<td><b>Max Reduce Tasks</b></td>" +
-                "<td><b>Failures</b></td>" +
-                "<td><b>Seconds since heartbeat</b></td></tr>\n");
+      out.print("<table class=\"datatable\">\n");
+      out.print("<thead>\n");
+      out.print("<tr><th><b>Name</b></th><th><b>Host</b></th>" +
+                "<th><b># running tasks</b></th>" +
+                "<th><b>Max Map Tasks</b></th>" +
+                "<th><b>Max Reduce Tasks</b></th>" +
+                "<th><b>Failures</b></th>" +
+                "<th><b>Seconds since heartbeat</b></th></tr>\n");
+      out.print("</thead><tbody>");
       int maxFailures = 0;
       String failureKing = null;
       for (Iterator it = c.iterator(); it.hasNext(); ) {
@@ -65,6 +66,7 @@
                   "</td><td>" + numFailures + 
                   "</td><td>" + sinceHeartbeat + "</td></tr>\n");
       }
+      out.print("</tbody>\n");
       out.print("</table>\n");
       out.print("</center>\n");
       if (maxFailures > 0) {
@@ -77,9 +79,11 @@
 %>
 
 <html>
-
+<head>
 <title><%=trackerName%> Hadoop Machine List</title>
-
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h1><a href="jobtracker.jsp"><%=trackerName%></a> Hadoop Machine List</h1>
 
diff --git a/src/webapps/job/taskdetails.jsp b/src/webapps/job/taskdetails.jsp
index bd5981c..6cf5b6b 100644
--- a/src/webapps/job/taskdetails.jsp
+++ b/src/webapps/job/taskdetails.jsp
@@ -88,6 +88,7 @@
 <html>
 <head>
   <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+  <link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
   <title>Hadoop Task Details</title>
 </head>
 <body>
@@ -104,16 +105,19 @@
 <%
     } else {
 %>
-<table border=2 cellpadding="5" cellspacing="2">
-<tr><td align="center">Task Attempts</td><td>Machine</td><td>Status</td><td>Progress</td><td>Start Time</td> 
+<table class="jobtasks datatable">
+<thead>
+<tr><th align="center">Task Attempts</th><th>Machine</th><th>Status</th><th>Progress</th><th>Start Time</th> 
   <%
    if (!ts[0].getIsMap() && !isCleanupOrSetup) {
    %>
-<td>Shuffle Finished</td><td>Sort Finished</td>
+<th>Shuffle Finished</th><th>Sort Finished</th>
   <%
   }
   %>
-<td>Finish Time</td><td>Errors</td><td>Task Logs</td><td>Counters</td><td>Actions</td></tr>
+<th>Finish Time</th><th>Errors</th><th>Task Logs</th><th>Counters</th><th>Actions</th></tr>
+  </thead>
+  <tbody>
   <%
     for (int i = 0; i < ts.length; i++) {
       TaskStatus status = ts[i];
@@ -245,6 +249,7 @@
         out.println("</td></tr>");
       }
   %>
+</tbody>
 </table>
 </center>
 
@@ -252,7 +257,7 @@
       if (ts[0].getIsMap() && !isCleanupOrSetup) {
 %>
 <h3>Input Split Locations</h3>
-<table border=2 cellpadding="5" cellspacing="2">
+<table class="datatable">
 <%
         for (String split: StringUtils.split(tracker.getTip(
                                          tipidObj).getSplitNodes())) {
diff --git a/src/webapps/job/taskdetailshistory.jsp b/src/webapps/job/taskdetailshistory.jsp
index a7c4f17..7672e2b 100644
--- a/src/webapps/job/taskdetailshistory.jsp
+++ b/src/webapps/job/taskdetailshistory.jsp
@@ -25,24 +25,33 @@
   String type = task.get(Keys.TASK_TYPE);
 %>
 <html>
+<head>
+<title><%=taskid %> attempts for <%=jobid %></title>
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h2><%=taskid %> attempts for <a href="jobdetailshistory.jsp?jobid=<%=jobid%>&&logFile=<%=encodedLogFileName%>"> <%=jobid %> </a></h2>
 <center>
-<table border="2" cellpadding="5" cellspacing="2">
-<tr><td>Task Id</td><td>Start Time</td>
+<table class="jobtasks datatable">
+<thead>
+<tr><th>Task Id</th><th>Start Time</th>
 <%	
   if (Values.REDUCE.name().equals(type)) {
 %>
-    <td>Shuffle Finished</td><td>Sort Finished</td>
+    <th>Shuffle Finished</th><th>Sort Finished</th>
 <%
   }
 %>
-<td>Finish Time</td><td>Host</td><td>Error</td><td>Task Logs</td></tr>
+<th>Finish Time</th><th>Host</th><th>Error</th><th>Task Logs</th></tr>
+</thead>
+<tbody>
 <%
   for (JobHistory.TaskAttempt attempt : task.getTaskAttempts().values()) {
     printTaskAttempt(attempt, type, out);
   }
 %>
+</tbody>
 </table>
 </center>
 <%	
diff --git a/src/webapps/job/taskstats.jsp b/src/webapps/job/taskstats.jsp
index dc7ccbc..0a20412 100644
--- a/src/webapps/job/taskstats.jsp
+++ b/src/webapps/job/taskstats.jsp
@@ -38,6 +38,8 @@
 <html>
   <head>
     <title>Counters for <%=taskid%></title>
+    <link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+    <link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
   </head>
 <body>
 <h1>Counters for <%=taskid%></h1>
diff --git a/src/webapps/static/hadoop.css b/src/webapps/static/hadoop.css
index 0560cb3..ea2160d 100644
--- a/src/webapps/static/hadoop.css
+++ b/src/webapps/static/hadoop.css
@@ -132,3 +132,54 @@ line.taskgraphline {
 #quicklinks ul a {
 	text-decoration: underline;
 }
+
+/**
+ * Style additions by Cloudera
+ */
+
+body {
+  background-color : #fff;
+  font-family : sans-serif;
+  font-size:11px;
+  line-height:17px;
+}
+
+table td, table th {
+  font-size: 12px;
+}
+
+a { 
+  color: #04f !important; 
+  text-decoration:none !important;
+}
+
+a:hover {
+  text-decoration:underline;
+}
+
+hr {
+  border:1px solid #ddd;
+  border-top:0px;
+}
+
+table.datatable td, table.datatable th{
+  border: 1px solid #666;
+  padding: 5px;
+  margin: 2px;
+}
+
+table.nnbrowse td {
+  font-family: courier,sans-serif;
+}
+
+table.datatable tbody tr:nth-child(even) { background: #cacaff; }
+table.datatable {
+  font-size: 10px;
+}
+
+table {
+  border-collapse: collapse;
+}
+table td {
+  border: 1px;
+}
diff --git a/src/webapps/static/images/favicon.ico b/src/webapps/static/images/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..dc926b2c8448fd52bec92102100865a609a3eb0f
GIT binary patch
literal 1150
zcma)3O-NKx6h1~E)S@AwmC)N+1T6|&I&NG=;6@0_MU<$!+7zTRn-pah2~&%HgjUre
zDU%AFl40H(W^!a4nwTeQI;G>hAMYFI-H~x{^muMIFuS?m<9p}u-S0d1UM@fbeI5_c
zUxB`p0OtVU0+A$Aj&&;k&~zF=P!>EFx?albJ+l5<A6xKumHGM_;z4t*F4OO>PTz9Z
zzartPjK9`X+Dcq<V!nMkw^pmm_QmB-Q8qt}MV1W6W~#nDQ*U)*BbZN&BexgcRCU?9
z`zQV~JKcrOVgUJe@|SE*_{#Q@#|S^ork?|DOx;A5et*Eth$1_qWTo1j<OJGLAF{*~
z;xjC)efG=d%Xz(bGdPCJuba_P`_cLN0*hv($c>29`&V{;-_J}vz(qeG3*AK)zK4a4
z@8}xZxXc;$^DDPEXNNH|1o(Hd1Gne8k;TW5_OEb5y<Bfb+19T(iFb$U0APF+&<=K@
z6}*8gHQ{jUN3?F<N;ekt*@x;N<id{tQvs-0GuP1k);;NNg+6dY>#sLMtW&l}qdRDW
zFqi$<cE|kU9ThsaVy|37y(s#6p!{Q+(<yw`OvedP=?-VzoZ2G#D$uJahs26cQTFhd
aJ5&WTq!CYLyi^6x|K}O<wNU1*q8tH_d=%aQ

literal 0
HcmV?d00001

diff --git a/src/webapps/static/jobconf.xsl b/src/webapps/static/jobconf.xsl
index f3c2e33..4e086ad 100644
--- a/src/webapps/static/jobconf.xsl
+++ b/src/webapps/static/jobconf.xsl
@@ -2,17 +2,21 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:output method="html"/>
 <xsl:template match="configuration">
-<table border="1" align="center" >
+<table border="1" align="center" class="datatable">
+<thead>
 <tr>
  <th>name</th>
  <th>value</th>
 </tr>
+</thead>
+<tbody>
 <xsl:for-each select="property">
 <tr>
   <td width="35%"><b><xsl:value-of select="name"/></b></td>
   <td width="65%"><xsl:value-of select="value"/></td>
 </tr>
 </xsl:for-each>
+</tbody>
 </table>
 </xsl:template>
 </xsl:stylesheet>
diff --git a/src/webapps/task/tasktracker.jsp b/src/webapps/task/tasktracker.jsp
index 7f818d9..f60f5e0 100644
--- a/src/webapps/task/tasktracker.jsp
+++ b/src/webapps/task/tasktracker.jsp
@@ -14,9 +14,11 @@
 %>
 
 <html>
-
+<head>
 <title><%= trackerName %> Task Tracker Status</title>
-
+<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
+<link rel="icon" type="image/vnd.microsoft.icon" href="/static/images/favicon.ico" />
+</head>
 <body>
 <h1><%= trackerName %> Task Tracker Status</h1>
 <img src="/static/hadoop-logo.jpg"/><br>
-- 
1.6.0.4

