Browse Source

HUE-1059 [oozie] Display all Oozie web UI information

New 'Oozie' tab on the dashboard
Added some missing job fields on the pages
Romain Rigaux 12 năm trước cách đây
mục cha
commit
5ef487d

+ 5 - 5
apps/jobbrowser/src/jobbrowser/templates/job.mako

@@ -331,7 +331,7 @@ ${ commonheader(_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short),
             "aaSorting": [[ 1, "asc" ]],
             "oLanguage": {
                 "sEmptyTable": "${_('No data available')}",
-                "sZeroRecords": "${_('No matching records')}",
+                "sZeroRecords": "${_('No matching records')}"
             }
         });
 
@@ -346,7 +346,7 @@ ${ commonheader(_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short),
             ],
             "oLanguage": {
                 "sEmptyTable": "${_('No data available')}",
-                "sZeroRecords": "${_('No matching records')}",
+                "sZeroRecords": "${_('No matching records')}"
             }
         });
 
@@ -361,11 +361,11 @@ ${ commonheader(_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short),
             ],
             "oLanguage": {
                 "sEmptyTable": "${_('No data available')}",
-                "sZeroRecords": "${_('No matching records')}",
+                "sZeroRecords": "${_('No matching records')}"
             }
         });
 
-        $("#metadataFilter").keydown(function(){
+        $("#metadataFilter").keyup(function(){
             _metadataTable.fnFilter($(this).val());
             _rawConfigurationTable.fnFilter($(this).val());
         });
@@ -383,7 +383,7 @@ ${ commonheader(_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short),
             ],
             "oLanguage": {
                 "sEmptyTable": "${_('No data available')}",
-                "sZeroRecords": "${_('No matching records')}",
+                "sZeroRecords": "${_('No matching records')}"
             }
         });
 

+ 8 - 8
apps/oozie/src/oozie/migrations/0018_auto__add_field_workflow_managed.py

@@ -5,19 +5,19 @@ from south.v2 import SchemaMigration
 from django.db import models
 
 class Migration(SchemaMigration):
-    
+
     def forwards(self, orm):
-        
+
         # Adding field 'Workflow.managed'
         db.add_column('oozie_workflow', 'managed', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True), keep_default=False)
-    
-    
+
+
     def backwards(self, orm):
-        
+
         # Deleting field 'Workflow.managed'
         db.delete_column('oozie_workflow', 'managed')
-    
-    
+
+
     models = {
         'auth.group': {
             'Meta': {'object_name': 'Group'},
@@ -300,5 +300,5 @@ class Migration(SchemaMigration):
             'start': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'start_workflow'", 'blank': 'True', 'null': 'True', 'to': "orm['oozie.Start']"})
         }
     }
-    
+
     complete_apps = ['oozie']

+ 12 - 2
apps/oozie/src/oozie/templates/dashboard/list_oozie_bundle.mako

@@ -131,7 +131,8 @@ ${ layout.menubar(section='dashboard') }
           <thead>
           <tr>
             <th>${ _('Day') }</th>
-            <th>${ _('Comment') }</th>
+            <th>${ _('Last action') }</th>
+            <th>${ _('Next materialization') }</th>
           </tr>
           </thead>
           <tbody data-bind="template: {name: 'calendarTemplate', foreach: actions}">
@@ -161,6 +162,7 @@ ${ layout.menubar(section='dashboard') }
             </a>
           </td>
           <td><span data-bind="text: lastAction"></span></td>
+          <td><span data-bind="text: nextMaterializedTime"></span></td>
         </tr>
       </script>
 
@@ -173,6 +175,10 @@ ${ layout.menubar(section='dashboard') }
             <th>${ _('Id') }</th>
 
             <th>${ _('Last action') }</th>
+
+            <th>${ _('Frequency') }</th>
+            <th>${ _('Time Unit') }</th>
+
             <th>${ _('Acl') }</th>
 
             <th>${ _('Type') }</th>
@@ -215,6 +221,8 @@ ${ layout.menubar(section='dashboard') }
             <a data-bind="visible:externalId !='', attr: {href: url}, text: id" data-row-selector"true"></a>
           </td>
           <td data-bind="text: lastAction"></td>
+          <td data-bind="text: frequency"></td>
+          <td data-bind="text: timeUnit"></td>
           <td data-bind="text: acl"></td>
           <td data-bind="text: type"></td>
           <td><span data-bind="text: status, attr: {'class': statusClass}"></span></td>
@@ -290,6 +298,7 @@ ${ layout.menubar(section='dashboard') }
       statusClass: "label " + getStatusClass(action.status),
       externalId: action.externalId,
       frequency: action.frequency,
+      timeUnit: action.timeUnit,
       concurrency: action.concurrency,
       pauseTime: action.pauseTime,
       acl: action.acl,
@@ -299,7 +308,8 @@ ${ layout.menubar(section='dashboard') }
       executionPolicy: action.executionPolicy,
       startTime: action.startTime,
       endTime: action.endTime,
-      lastAction: action.lastAction
+      lastAction: action.lastAction,
+      nextMaterializedTime: action.nextMaterializedTime
     }
   }
 

+ 11 - 4
apps/oozie/src/oozie/templates/dashboard/list_oozie_bundles.mako

@@ -61,9 +61,10 @@ ${layout.menubar(section='dashboard')}
         <tr>
           <th width="15%">${ _('Kickoff Time') }</th>
           <th width="10%">${ _('Status') }</th>
-          <th width="25%">${ _('Name') }</th>
+          <th width="20%">${ _('Name') }</th>
           <th width="10%">${ _('Progress') }</th>
-          <th width="15%">${ _('Submitter') }</th>
+          <th width="10%">${ _('Submitter') }</th>
+          <th width="10%">${ _('Created Time') }</th>
           <th width="15%">${ _('Id') }</th>
           <th width="10%">${ _('Action') }</th>
         </tr>
@@ -81,8 +82,9 @@ ${layout.menubar(section='dashboard')}
         <tr>
           <th width="15%">${ _('Kickoff Time') }</th>
           <th width="10%">${ _('Status') }</th>
-          <th width="35%">${ _('Name') }</th>
+          <th width="25%">${ _('Name') }</th>
           <th width="15%">${ _('Submitter') }</th>
+          <th width="15%">${ _('Created Time') }</th>
           <th width="25%">${ _('Id') }</th>
         </tr>
       </thead>
@@ -124,7 +126,8 @@ ${layout.menubar(section='dashboard')}
       user: bundle.user,
       absoluteUrl: bundle.absoluteUrl,
       canEdit: bundle.canEdit,
-      killUrl: bundle.killUrl
+      killUrl: bundle.killUrl,
+      created: bundle.created
     }
   }
 
@@ -141,6 +144,7 @@ ${layout.menubar(section='dashboard')}
         { "sSortDataType":"dom-sort-value", "sType":"numeric" },
         null,
         null,
+        null,
         { "bSortable":false }
       ],
       "aaSorting":[
@@ -174,6 +178,7 @@ ${layout.menubar(section='dashboard')}
         null,
         null,
         null,
+        null,
         null
       ],
       "aaSorting":[
@@ -342,6 +347,7 @@ ${layout.menubar(section='dashboard')}
                     bundle.appName,
                     '<div class="progress"><div class="' + bundle.progressClass + '" style="width:' + bundle.progress + '%">' + bundle.progress + '%</div></div>',
                     bundle.user,
+                    bundle.created,
                     '<a href="' + bundle.absoluteUrl + '" data-row-selector="true">' + bundle.id + '</a>',
                     killCell]);
               }
@@ -376,6 +382,7 @@ ${layout.menubar(section='dashboard')}
               '<span class="' + bundle.statusClass + '">' + bundle.status + '</span>',
               bundle.appName,
               bundle.user,
+              bundle.created,
               '<a href="' + bundle.absoluteUrl + '" data-row-selector="true">' + bundle.id + '</a>'
           ], false);
         });

+ 3 - 0
apps/oozie/src/oozie/templates/dashboard/list_oozie_coordinator.mako

@@ -194,6 +194,7 @@ ${ layout.menubar(section='dashboard') }
             <th>${ _('Type') }</th>
             <th>${ _('Status') }</th>
 
+            <th>${ _('Error Code') }</th>
             <th>${ _('Error Message') }</th>
             <th>${ _('Missing Dependencies') }</th>
 
@@ -231,6 +232,7 @@ ${ layout.menubar(section='dashboard') }
           <td data-bind="text: nominalTime"></td>
           <td data-bind="text: type"></td>
           <td><span data-bind="text: status, attr: {'class': statusClass}"></span></td>
+          <td data-bind="text: errorCode"></td>
           <td data-bind="text: errorMessage"></td>
           <td data-bind="text: missingDependencies"></td>
           <td data-bind="text: createdTime"></td>
@@ -314,6 +316,7 @@ ${ layout.menubar(section='dashboard') }
       createdTime: action.createdTime,
       lastModifiedTime: action.lastModifiedTime,
       errorMessage: action.errorMessage,
+      errorCode: action.errorCode,
       missingDependencies: action.missingDependencies
     }
   }

+ 56 - 27
apps/oozie/src/oozie/templates/dashboard/list_oozie_coordinators.mako

@@ -58,11 +58,14 @@ ${layout.menubar(section='dashboard')}
     <table class="table table-condensed" id="running-table">
       <thead>
         <tr>
-          <th width="15%">${ _('Next submission') }</th>
+          <th width="10%">${ _('Next submission') }</th>
           <th width="10%">${ _('Status') }</th>
-          <th width="25%">${ _('Name') }</th>
-          <th width="10%">${ _('Progress') }</th>
-          <th width="15%">${ _('Submitter') }</th>
+          <th width="20%">${ _('Name') }</th>
+          <th width="5%">${ _('Progress') }</th>
+          <th width="10%">${ _('Submitter') }</th>
+          <th width="5%">${ _('Frequency') }</th>
+          <th width="5%">${ _('Time unit') }</th>
+          <th width="5%">${ _('Started') }</th>
           <th width="15%">${ _('Id') }</th>
           <th width="10%">${ _('Action') }</th>
         </tr>
@@ -78,11 +81,14 @@ ${layout.menubar(section='dashboard')}
     <table class="table table-condensed" id="completed-table" data-tablescroller-disable="true">
       <thead>
         <tr>
-          <th width="15%">${ _('Completion') }</th>
-          <th width="10%">${ _('Status') }</th>
-          <th width="30%">${ _('Name') }</th>
+          <th width="10%">${ _('Completion') }</th>
+          <th width="5%">${ _('Status') }</th>
+          <th width="25%">${ _('Name') }</th>
           <th width="10%">${ _('Duration') }</th>
-          <th width="15%">${ _('Submitter') }</th>
+          <th width="10%">${ _('Submitter') }</th>
+          <th width="5%">${ _('Frequency') }</th>
+          <th width="5%">${ _('Time unit') }</th>
+          <th width="5%">${ _('Started') }</th>
           <th width="20%">${ _('Id') }</th>
         </tr>
       </thead>
@@ -112,19 +118,22 @@ ${layout.menubar(section='dashboard')}
 
   var Coordinator = function (c) {
     return {
-      id:c.id,
-      endTime:c.endTime,
-      status:c.status,
-      statusClass:"label " + getStatusClass(c.status),
-      isRunning:c.isRunning,
-      duration:c.duration,
-      appName:decodeURIComponent(c.appName),
-      progress:c.progress,
-      progressClass:"bar " + getStatusClass(c.status, "bar-"),
-      user:c.user,
-      absoluteUrl:c.absoluteUrl,
-      canEdit:c.canEdit,
-      killUrl:c.killUrl
+      id: c.id,
+      endTime: c.endTime,
+      status: c.status,
+      statusClass: "label " + getStatusClass(c.status),
+      isRunning: c.isRunning,
+      duration: c.duration,
+      appName: decodeURIComponent(c.appName),
+      progress: c.progress,
+      progressClass: "bar " + getStatusClass(c.status, "bar-"),
+      user: c.user,
+      absoluteUrl: c.absoluteUrl,
+      canEdit: c.canEdit,
+      killUrl: c.killUrl,
+      frequency: c.frequency,
+      timeUnit: c.timeUnit,
+      created: c.created
     }
   }
 
@@ -141,6 +150,9 @@ ${layout.menubar(section='dashboard')}
         { "sSortDataType":"dom-sort-value", "sType":"numeric" },
         null,
         null,
+        null,
+        null,
+        null,
         { "bSortable":false }
       ],
       "aaSorting":[
@@ -175,6 +187,9 @@ ${layout.menubar(section='dashboard')}
         null,
         { "sSortDataType":"dom-sort-value", "sType":"numeric" },
         null,
+        null,
+        null,
+        null,
         null
       ],
       "aaSorting":[
@@ -337,9 +352,17 @@ ${layout.menubar(section='dashboard')}
                         '>${ _('Kill') }</a>';
               }
               if (['RUNNING', 'PREP', 'WAITING', 'SUSPENDED', 'PREPSUSPENDED', 'PREPPAUSED', 'PAUSED'].indexOf(coord.status) > -1) {
-                runningTable.fnAddData([coord.endTime, '<span class="' + coord.statusClass + '">' + coord.status + '</span>', coord.appName,
-                  '<div class="progress"><div class="' + coord.progressClass + '" style="width:' + coord.progress + '%">' + coord.progress + '%</div></div>', coord.user, '<a href="' + coord.absoluteUrl + '" data-row-selector="true">' + coord.id + '</a>',
-                  killCell]);
+                runningTable.fnAddData([
+                  coord.endTime, '<span class="' + coord.statusClass + '">' + coord.status + '</span>',
+                  coord.appName,
+                  '<div class="progress"><div class="' + coord.progressClass + '" style="width:' + coord.progress + '%">' + coord.progress + '%</div></div>',
+                  coord.user,
+				  coord.frequency,
+				  coord.timeUnit,
+				  coord.created,
+				  '<a href="' + coord.absoluteUrl + '" data-row-selector="true">' + coord.id + '</a>',
+                  killCell
+                ]);
               }
 
             }
@@ -367,13 +390,19 @@ ${layout.menubar(section='dashboard')}
         completedTable.fnClearTable();
         $(data).each(function (iWf, item) {
           var coord = new Coordinator(item);
-          completedTable.fnAddData([coord.endTime, '<span class="' + coord.statusClass + '">' + coord.status + '</span>', coord.appName,
-            coord.duration, coord.user, '<a href="' + coord.absoluteUrl + '" data-row-selector="true">' + coord.id + '</a>'], false);
+          completedTable.fnAddData([
+            coord.endTime, '<span class="' + coord.statusClass + '">' + coord.status + '</span>',
+            coord.appName,
+            coord.duration,
+            coord.user,
+            coord.frequency,
+            coord.timeUnit,
+            coord.created,
+            '<a href="' + coord.absoluteUrl + '" data-row-selector="true">' + coord.id + '</a>'], false);
         });
         completedTable.fnDraw();
       });
     }
-
   });
 </script>
 

+ 190 - 0
apps/oozie/src/oozie/templates/dashboard/list_oozie_info.mako

@@ -0,0 +1,190 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+
+<%!
+  from desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="layout" file="../navigation-bar.mako" />
+<%namespace name="utils" file="../utils.inc.mako" />
+
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
+${ layout.menubar(section='dashboard') }
+
+
+<div class="container-fluid">
+  ${ layout.dashboard_sub_menubar(section='oozie') }
+
+  <h1>Oozie</h1>
+
+
+<div class="row-fluid">
+  <div class="span2">
+    <div class="well sidebar-nav">
+      <ul class="nav nav-list">
+        <li class="nav-header">${ _('Status') }</li>
+        <li>
+          <span class="label ${ utils.get_status(oozie_status['systemMode']) }">
+            ${ oozie_status['systemMode'] }
+          </span>
+        </li>
+      </ul>
+    </div>
+  </div>
+  <div class="span10">
+    <ul class="nav nav-tabs">
+      <li class="active"><a href="#instrumentation" data-toggle="tab">${ _('Instrumentation') }</a></li>
+      <li><a href="#configuration" data-toggle="tab">${ _('Configuration') }</a></li>
+    </ul>
+
+    <div class="tab-content" style="padding-bottom:200px">
+      <div class="tab-pane active" id="instrumentation">
+        <div class="well hueWell">
+            <form class="form-search">
+                ${_('Filter: ')}<input type="text" class="searchFilter input-xlarge search-query" placeholder="${_('Text Filter')}">
+            </form>
+        </div>
+       <div class="tabbable">
+          <ul class="nav nav-pills">
+            % for category in instrumentation.iterkeys():
+            <li
+            % if loop.first:
+              class="active"
+            % endif
+            >
+              <a href="#${ category }" data-toggle="tab">${ category }</a>
+            </li>
+            % endfor
+          </ul>
+
+         <div class="tab-content">
+          % for category in instrumentation.iterkeys():
+            <div class="tab-pane
+              % if loop.first:
+                active
+              % endif
+            " id="${ category }">
+
+              % for index, group in enumerate(instrumentation[category]):
+                  <p class="nav-header">${ group['group'] }</p>
+                    <table id="intrumentationTable-${ category }-${ index }" class="table table-striped table-condensed">
+                        <thead>
+                            <th> </th>
+                            <th> </th>
+                        </thead>
+                        <tbody>
+                          % for item in group['data']:
+                            <tr>
+                              <td>${ item.pop('name') }</td>
+                              <td>${ ', '.join(map(str, item.values())) }</td>
+                            </tr>
+                          % endfor
+                        </tbody>
+                    </table>
+              % endfor
+            </div>
+          % endfor
+         </div>
+       </div>
+
+      </div>
+
+      <div class="tab-pane" id="configuration">
+        <div class="well hueWell">
+            <form class="form-search">
+                ${_('Filter: ')}<input type="text" class="searchFilter input-xlarge search-query" placeholder="${_('Text Filter')}">
+            </form>
+        </div>
+        ${ utils.display_conf(configuration, "configurationTable") }
+      </div>
+
+
+    <div style="margin-bottom: 16px">
+      <a href="${ url('oozie:list_oozie_bundles') }" class="btn">${ _('Back') }</a>
+    </div>
+
+  </div>
+</div>
+
+
+
+</div>
+
+<style>
+  .sidebar-nav {
+    padding: 9px 0;
+  }
+</style>
+
+<script>
+  $(document).ready(function(){
+    $("a[data-row-selector='true']").jHueRowSelector();
+
+    $("*[rel=tooltip]").tooltip();
+
+        var _metadataTable = $("#configurationTable").dataTable({
+            "bPaginate": false,
+            "bLengthChange": false,
+            "bInfo": false,
+            "bAutoWidth": false,
+            "aoColumns": [
+                { "sWidth": "30%" },
+                { "sWidth": "70%" }
+            ],
+            "oLanguage": {
+                "sEmptyTable": "${_('No data available')}",
+                "sZeroRecords": "${_('No matching records')}",
+            }
+        });
+
+   var instrumentationTables = [];
+
+   % for category in instrumentation.iterkeys():
+      % for index in range(len(instrumentation[category])):
+        var table = $("#intrumentationTable-${ category }-${ index }").dataTable({
+            "bPaginate": false,
+            "bLengthChange": false,
+            "bInfo": false,
+            "bAutoWidth": false,
+            "aoColumns": [
+                { "sWidth": "30%" },
+                { "sWidth": "70%" }
+            ],
+            "oLanguage": {
+                "sEmptyTable": "${_('No data available')}",
+                "sZeroRecords": "${_('No matching records')}"
+            }
+        });
+        $("#intrumentationTable-${ category }-${ index } th").removeClass();
+        instrumentationTables.push(table);
+      % endfor
+    % endfor
+
+
+    $(".searchFilter").keyup(function(){
+        _metadataTable.fnFilter($(this).val());
+        $.each(instrumentationTables, function(index, item){
+          item.fnFilter($(".searchFilter").val());
+        });
+    });
+
+    $(".dataTables_wrapper").css("min-height","0");
+    $(".dataTables_filter").hide();
+  });
+</script>
+
+${ commonfooter(messages) | n,unicode }

+ 3 - 0
apps/oozie/src/oozie/templates/dashboard/list_oozie_workflow.mako

@@ -178,6 +178,7 @@ ${ layout.menubar(section='dashboard') }
               <th>${ _('End Time') }</th>
 
               <th>${ _('Retries') }</th>
+              <th>${ _('Error Code') }</th>
               <th>${ _('Error Message') }</th>
               <th>${ _('Transition') }</th>
 
@@ -219,6 +220,7 @@ ${ layout.menubar(section='dashboard') }
             <td data-bind="text: endTime"></td>
 
             <td data-bind="text: retries"></td>
+            <td data-bind="text: errorCode"></td>
             <td data-bind="text: errorMessage"></td>
             <td data-bind="text: transition"></td>
 
@@ -326,6 +328,7 @@ ${ layout.menubar(section='dashboard') }
       endTime: action.endTime,
       retries: action.retries,
       errorMessage: action.errorMessage,
+      errorCode: action.errorCode,
       transition: action.transition,
       data: action.data
     }

+ 56 - 28
apps/oozie/src/oozie/templates/dashboard/list_oozie_workflows.mako

@@ -59,11 +59,14 @@ ${ layout.menubar(section='dashboard') }
     <table class="table table-condensed" id="running-table">
       <thead>
         <tr>
-          <th width="15%">${ _('Submission') }</th>
+          <th width="10%">${ _('Submission') }</th>
           <th width="10%">${ _('Status') }</th>
-          <th width="30%">${ _('Name') }</th>
-          <th width="10%">${ _('Progress') }</th>
-          <th width="10%">${ _('Submitter') }</th>
+          <th width="20%">${ _('Name') }</th>
+          <th width="5%">${ _('Progress') }</th>
+          <th width="5%">${ _('Submitter') }</th>
+          <th width="10%">${ _('Created') }</th>
+          <th width="10%">${ _('Last modified') }</th>
+          <th width="5%">${ _('Run') }</th>
           <th width="15%">${ _('Id') }</th>
           <th width="10%">${ _('Action') }</th>
         </tr>
@@ -80,12 +83,15 @@ ${ layout.menubar(section='dashboard') }
     <table class="table table-condensed" id="completed-table" data-tablescroller-disable="true">
       <thead>
         <tr>
-          <th width="15%">${ _('Completion') }</th>
+          <th width="10%">${ _('Completion') }</th>
           <th width="10%">${ _('Status') }</th>
-          <th width="35%">${ _('Name') }</th>
-          <th width="10%">${ _('Duration') }</th>
-          <th width="10%">${ _('Submitter') }</th>
-          <th width="20%">${ _('Id') }</th>
+          <th width="25%">${ _('Name') }</th>
+          <th width="5%">${ _('Duration') }</th>
+          <th width="5%">${ _('Submitter') }</th>
+          <th width="10%">${ _('Created') }</th>
+          <th width="10%">${ _('Last modified') }</th>
+          <th width="5%">${ _('Run') }</th>
+          <th width="25%">${ _('Id') }</th>
         </tr>
       </thead>
       <tbody>
@@ -111,23 +117,24 @@ ${ layout.menubar(section='dashboard') }
 <script src="/static/ext/js/datatables-paging-0.1.js" type="text/javascript" charset="utf-8"></script>
 
 <script type="text/javascript" charset="utf-8">
-
   var Workflow = function (wf) {
     return {
-      id:wf.id,
-      lastModTime:wf.lastModTime,
-      endTime:wf.endTime,
-      status:wf.status,
-      statusClass:"label " + getStatusClass(wf.status),
-      isRunning:wf.isRunning,
-      duration:wf.duration,
-      appName:wf.appName,
-      progress:wf.progress,
-      progressClass:"bar " + getStatusClass(wf.status, "bar-"),
-      user:wf.user,
-      absoluteUrl:wf.absoluteUrl,
-      canEdit:wf.canEdit,
-      killUrl:wf.killUrl
+      id: wf.id,
+      lastModTime: wf.lastModTime,
+      endTime: wf.endTime,
+      status: wf.status,
+      statusClass: "label " + getStatusClass(wf.status),
+      isRunning: wf.isRunning,
+      duration: wf.duration,
+      appName: wf.appName,
+      progress: wf.progress,
+      progressClass: "bar " + getStatusClass(wf.status, "bar-"),
+      user: wf.user,
+      absoluteUrl: wf.absoluteUrl,
+      canEdit: wf.canEdit,
+      killUrl: wf.killUrl,
+      created: wf.created,
+      run: wf.run
     }
   }
 
@@ -144,6 +151,9 @@ ${ layout.menubar(section='dashboard') }
         { "sSortDataType":"dom-sort-value", "sType":"numeric" },
         null,
         null,
+        null,
+        null,
+        null,
         { "bSortable":false }
       ],
       "aaSorting":[
@@ -178,6 +188,9 @@ ${ layout.menubar(section='dashboard') }
         null,
         { "sSortDataType":"dom-sort-value", "sType":"numeric" },
         null,
+        null,
+        null,
+        null,
         null
       ],
       "aaSorting":[
@@ -335,8 +348,16 @@ ${ layout.menubar(section='dashboard') }
                         '>${ _('Kill') }</a>';
               }
               if (['RUNNING', 'PREP', 'WAITING', 'SUSPENDED', 'PREPSUSPENDED', 'PREPPAUSED', 'PAUSED'].indexOf(wf.status) > -1) {
-                runningTable.fnAddData([wf.lastModTime, '<span class="' + wf.statusClass + '">' + wf.status + '</span>', wf.appName,
-                  '<div class="progress"><div class="' + wf.progressClass + '" style="width:' + wf.progress + '%">' + wf.progress + '%</div></div>', wf.user, '<a href="' + wf.absoluteUrl + '" data-row-selector="true">' + wf.id + '</a>',
+                runningTable.fnAddData([
+                  wf.lastModTime,
+                  '<span class="' + wf.statusClass + '">' + wf.status + '</span>',
+                  wf.appName,
+                  '<div class="progress"><div class="' + wf.progressClass + '" style="width:' + wf.progress + '%">' + wf.progress + '%</div></div>',
+                  wf.user,
+                  wf.created,
+                  wf.lastModTime,
+                  wf.run,
+                  '<a href="' + wf.absoluteUrl + '" data-row-selector="true">' + wf.id + '</a>',
                   killCell]);
               }
             }
@@ -364,8 +385,15 @@ ${ layout.menubar(section='dashboard') }
         completedTable.fnClearTable();
         $(data).each(function (iWf, item) {
           var wf = new Workflow(item);
-          completedTable.fnAddData([wf.endTime, '<span class="' + wf.statusClass + '">' + wf.status + '</span>', decodeURIComponent(wf.appName),
-            wf.duration, wf.user, '<a href="' + wf.absoluteUrl + '" data-row-selector="true">' + wf.id + '</a>'], false);
+          completedTable.fnAddData([
+            wf.endTime,
+            '<span class="' + wf.statusClass + '">' + wf.status + '</span>', decodeURIComponent(wf.appName),
+            wf.duration,
+            wf.user,
+            wf.created,
+            wf.lastModTime,
+            wf.run,
+            '<a href="' + wf.absoluteUrl + '" data-row-selector="true">' + wf.id + '</a>'], false);
         });
         completedTable.fnDraw();
       });

+ 1 - 0
apps/oozie/src/oozie/templates/navigation-bar.mako

@@ -42,6 +42,7 @@
     <li class="${utils.is_selected(section, 'workflows')}"><a href="${url('oozie:list_oozie_workflows')}">${ _('Workflows') }</a></li>
     <li class="${utils.is_selected(section, 'coordinators')}"><a href="${url('oozie:list_oozie_coordinators')}">${ _('Coordinators') }</a></li>
     <li class="${utils.is_selected(section, 'bundles')}"><a href="${url('oozie:list_oozie_bundles')}">${ _('Bundles') }</a></li>
+    <li class="${utils.is_selected(section, 'oozie')}"><a href="${url('oozie:list_oozie_info')}">${ _('Oozie') }</a></li>
   </ul>
 </%def>
 

+ 7 - 3
apps/oozie/src/oozie/templates/utils.inc.mako

@@ -119,8 +119,12 @@
 </%def>
 
 
-<%def name="display_conf(configs)">
-  <table class="table table-condensed table-striped">
+<%def name="display_conf(configs, id=None)">
+  <table class="table table-condensed table-striped"
+    % if id is not None:
+      id="${ id }"
+    % endif
+  >
     <thead>
       <tr>
         <th>${ _('Name') }</th>
@@ -183,7 +187,7 @@
 
 
 <%def name="get_status(status)">
-   % if status in ('SUCCEEDED', 'OK'):
+   % if status in ('SUCCEEDED', 'OK', 'NORMAL'):
      label-success
    % elif status in ('RUNNING', 'PREP', 'WAITING', 'SUSPENDED', 'PREPSUSPENDED', 'PREPPAUSED', 'PAUSED'):
       label-warning

+ 2 - 0
apps/oozie/src/oozie/urls.py

@@ -86,4 +86,6 @@ urlpatterns += patterns(
   url(r'^rerun_oozie_job/(?P<job_id>[-\w]+)/(?P<app_path>.+?)$', 'rerun_oozie_job', name='rerun_oozie_job'),
   url(r'^rerun_oozie_coord/(?P<job_id>[-\w]+)/(?P<app_path>.+?)$', 'rerun_oozie_coordinator', name='rerun_oozie_coord'),
   url(r'^manage_oozie_jobs/(?P<job_id>[-\w]+)/(?P<action>(start|suspend|resume|kill|rerun))$', 'manage_oozie_jobs', name='manage_oozie_jobs'),
+
+  url(r'^list_oozie_info/$', 'list_oozie_info', name='list_oozie_info'),
 )

+ 23 - 1
apps/oozie/src/oozie/views/dashboard.py

@@ -306,6 +306,20 @@ def list_oozie_workflow_action(request, action, coordinator_job_id=None, bundle_
   })
 
 
+@show_oozie_error
+def list_oozie_info(request):
+
+  instrumentation = get_oozie().get_instrumentation()
+  configuration = get_oozie().get_configuration()
+  oozie_status = get_oozie().get_oozie_status()
+
+  return render('dashboard/list_oozie_info.mako', request, {
+    'instrumentation': instrumentation,
+    'configuration': configuration,
+    'oozie_status': oozie_status,
+  })
+
+
 @show_oozie_error
 def rerun_oozie_job(request, job_id, app_path):
   ParametersFormSet = formset_factory(ParameterForm, extra=0)
@@ -434,6 +448,7 @@ def massaged_workflow_actions_for_json(workflow_actions, oozie_coordinator, oozi
       'startTime': format_time(action.startTime),
       'endTime': format_time(action.endTime),
       'retries': action.retries,
+      'errorCode': escapejs(action.errorCode),
       'errorMessage': escapejs(action.errorMessage),
       'transition': action.transition,
       'data': escapejs(action.data)
@@ -465,6 +480,7 @@ def massaged_coordinator_actions_for_json(coordinator, oozie_bundle):
       'title': action.title,
       'createdTime': format_time(action.createdTime),
       'lastModifiedTime': format_time(action.lastModifiedTime),
+      'errorCode': escapejs(action.errorCode),
       'errorMessage': escapejs(action.errorMessage),
       'missingDependencies': escapejs(action.missingDependencies)
     }
@@ -487,6 +503,8 @@ def massaged_bundle_actions_for_json(bundle):
       'status': action.status,
       'externalId': action.coordExternalId or '-',
       'frequency': action.frequency,
+      'timeUnit': action.timeUnit,
+      'nextMaterializedTime': action.nextMaterializedTime,
       'concurrency': action.concurrency,
       'pauseTime': action.pauseTime,
       'user': action.user,
@@ -538,7 +556,11 @@ def massaged_oozie_jobs_for_json(oozie_jobs, user):
       'absoluteUrl': job.get_absolute_url(),
       'canEdit': has_job_edition_permission(job, user),
       'killUrl': reverse('oozie:manage_oozie_jobs', kwargs={'job_id':job.id, 'action':'kill'}),
-      }
+      'created': hasattr(job, 'createdTime') and job.createdTime and job.createdTime and ((job.type == 'Bundle' and job.createdTime) or format_time(job.createdTime)),
+      'run': hasattr(job, 'run') and job.run or 0,
+      'frequency': hasattr(job, 'frequency') and job.frequency or None,
+      'timeUnit': hasattr(job, 'timeUnit') and job.timeUnit or None,
+    }
     jobs.append(massaged_job)
 
   return jobs

+ 0 - 3
desktop/libs/liboozie/src/liboozie/oozie_api.py

@@ -282,9 +282,6 @@ class OozieApi(object):
     return resp
 
   def get_instrumentation(self):
-    """
-    get_instrumentation() -> Oozie instrumentation (dictionary)
-    """
     params = self._get_params()
     resp = self._root.get('admin/instrumentation', params)
     return resp