浏览代码

HUE-1176 [jb] Skeleton for browsing of Job tasks or Coordinator instances

Romain Rigaux 8 年之前
父节点
当前提交
a910751

+ 40 - 1
apps/jobbrowser/src/jobbrowser/apis/job_api.py

@@ -190,6 +190,7 @@ class YarnApi(Api):
       if app_property == 'tasks':
       if app_property == 'tasks':
         return {
         return {
           'task_list': YarnMapReduceTaskApi(self.user, appid).apps()['apps'],
           'task_list': YarnMapReduceTaskApi(self.user, appid).apps()['apps'],
+          'filter_text': ''
         }
         }
       elif app_property == 'metadata':
       elif app_property == 'metadata':
         return NativeYarnApi(self.user).get_job(jobid=appid).full_job_conf
         return NativeYarnApi(self.user).get_job(jobid=appid).full_job_conf
@@ -215,8 +216,46 @@ class YarnMapReduceTaskApi(Api):
 
 
 
 
   def apps(self):
   def apps(self):
+    filter_params = {
+      'task_types': None,
+      'task_states': None,
+      'task_text': None,
+      'jobid': self.app_id,
+      'pagenum': 1
+    }
+ 
+#     filter_params.update(_extract_query_params(filters)
+#     
+#     #filter_params['text']
+#  
+#     if filters.get('states'):
+#       filter_params['states'] = filters['states']
+#  
+#     if 'time' in filters:
+#       filter_params['time_value'] = int(filters['time']['time_value'])
+#       filter_params['time_unit'] = filters['time']['time_unit']
+ 
+#     jobs = NativeYarnApi(self.user).get_jobs(**filter_params)
+#  
+#     apps = [massage_job_for_json(job, user=self.user) for job in jobs]
+#  
+#     return {
+#       'apps': [{
+#         'id': app['id'],
+#         'name': app['name'],
+#         'type': app['applicationType'],
+#         'status': app['status'],
+#         'apiStatus': self._api_status(app['status']),
+#         'user': app['user'],
+#         'progress': app['progress'],
+#         'duration': app['durationMs'],
+#         'submitted': app['startTimeMs']
+#       } for app in apps],
+#       'total': None
+#     }
+
     return {
     return {
-      'apps': [self._massage_task(task) for task in NativeYarnApi(self.user).get_tasks(jobid=self.app_id, pagenum=1)],
+      'apps': [self._massage_task(task) for task in NativeYarnApi(self.user).get_tasks(**filter_params)],
       'total': None
       'total': None
     }
     }
 
 

+ 3 - 1
apps/jobbrowser/src/jobbrowser/apis/schedule_api.py

@@ -109,8 +109,10 @@ class ScheduleApi(Api):
       return 'RUNNING'
       return 'RUNNING'
     elif status in ['PREPSUSPENDED', 'SUSPENDED', 'SUSPENDEDWITHERROR', 'PREPPAUSED', 'PAUSED', 'PAUSEDWITHERROR']:
     elif status in ['PREPSUSPENDED', 'SUSPENDED', 'SUSPENDEDWITHERROR', 'PREPPAUSED', 'PAUSED', 'PAUSEDWITHERROR']:
       return 'PAUSED'
       return 'PAUSED'
+    elif status == 'SUCCEEDED':
+      return 'SUCCEEDED'
     else:
     else:
-      return 'FINISHED' # SUCCEEDED, DONEWITHERROR, KILLED, FAILED
+      return 'FINISHED' # DONEWITHERROR, KILLED, FAILED
 
 
 
 
 class MockGet():
 class MockGet():

+ 38 - 44
apps/jobbrowser/src/jobbrowser/templates/job_browser.mako

@@ -144,7 +144,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
             </select>
             </select>
 
 
             <div class="pull-right">
             <div class="pull-right">
-              <div data-bind="template: { name: 'actions', 'data': jobs }"></div>
+              <div data-bind="template: { name: 'job-actions', 'data': jobs }"></div>
             </div>
             </div>
 
 
             <div class="card card-small">
             <div class="card card-small">
@@ -374,7 +374,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
   ${ _('Duration') } <span data-bind="text: duration"></span>
   ${ _('Duration') } <span data-bind="text: duration"></span>
   ${ _('Submitted') } <span data-bind="text: submitted"></span>
   ${ _('Submitted') } <span data-bind="text: submitted"></span>
 
 
-  <div data-bind="template: { name: 'actions' }"></div>
+  <div data-bind="template: { name: 'job-actions' }"></div>
 </script>
 </script>
 
 
 
 
@@ -401,7 +401,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
     <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
     <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
   </div>
   </div>
 
 
-  <div data-bind="template: { name: 'actions' }"></div>
+  <div data-bind="template: { name: 'job-actions' }"></div>
 
 
   <ul class="nav nav-tabs margin-top-20">
   <ul class="nav nav-tabs margin-top-20">
     <li class="active"><a href="#job-mapreduce-page-logs" data-toggle="tab">${ _('Logs') }</a></li>
     <li class="active"><a href="#job-mapreduce-page-logs" data-toggle="tab">${ _('Logs') }</a></li>
@@ -421,7 +421,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
     </div>
     </div>
 
 
     <div class="tab-pane" id="job-mapreduce-page-tasks">
     <div class="tab-pane" id="job-mapreduce-page-tasks">
-      ${_('Filter')} <input type="text" class="input-xlarge search-query" placeholder="${_('Filter by id, name, user...')}" value="user:${ user.username }">
+      ${_('Filter')} <input type="text" class="input-xlarge search-query" placeholder="${_('Filter by id, name, user...')}">
       <span class="btn-group">
       <span class="btn-group">
         <class="btn-group">
         <class="btn-group">
           <a class="btn btn-status btn-success" data-value="completed">${ _('MAP') }</a>
           <a class="btn btn-status btn-success" data-value="completed">${ _('MAP') }</a>
@@ -429,13 +429,6 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
         </span>
         </span>
       </span>
       </span>
 
 
-      <div class="btn-toolbar pull-right" style="display: inline; vertical-align: middle; margin-left: 10px; font-size: 12px">
-        <span class="loader hide"><i class="fa fa-2x fa-spinner fa-spin muted"></i></span>
-        <button class="btn bulkToolbarBtn bulk-resume" data-operation="resume" title="${ _('Resume selected') }" disabled="disabled" type="button">
-          <i class="fa fa-play"></i><span class="hide-small"> ${ _('View') }</span>
-        </button>
-      </div>
-
       <table class="table table-condensed">
       <table class="table table-condensed">
         <thead>
         <thead>
         <tr>
         <tr>
@@ -524,13 +517,6 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
         </span>
         </span>
       </span>
       </span>
 
 
-      <div class="btn-toolbar pull-right" style="display: inline; vertical-align: middle; margin-left: 10px; font-size: 12px">
-        <span class="loader hide"><i class="fa fa-2x fa-spinner fa-spin muted"></i></span>
-        <button class="btn bulkToolbarBtn bulk-resume" data-operation="resume" title="${ _('Resume selected') }" disabled="disabled" type="button">
-          <i class="fa fa-play"></i><span class="hide-small"> ${ _('View') }</span>
-        </button>
-      </div>
-
       <table class="table table-condensed">
       <table class="table table-condensed">
         <thead>
         <thead>
         <tr>
         <tr>
@@ -659,11 +645,11 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
   ${ _('Duration') } <span data-bind="text: duration"></span>
   ${ _('Duration') } <span data-bind="text: duration"></span>
   ${ _('Submitted') } <span data-bind="text: submitted"></span>
   ${ _('Submitted') } <span data-bind="text: submitted"></span>
   
   
-  <div data-bind="template: { name: 'actions' }"></div>
+  <div data-bind="template: { name: 'job-actions' }"></div>
 </script>
 </script>
 
 
 
 
-<script type="text/html" id="actions">
+<script type="text/html" id="job-actions">
   <div class="btn-group">
   <div class="btn-group">
     <!-- ko if: hasResume -->
     <!-- ko if: hasResume -->
     <button class="btn" title="${ _('Resume selected') }" data-bind="click: function() { control('resume'); }, enable: resumeEnabled">
     <button class="btn" title="${ _('Resume selected') }" data-bind="click: function() { control('resume'); }, enable: resumeEnabled">
@@ -672,7 +658,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
     <!-- /ko -->
     <!-- /ko -->
 
 
     <!-- ko if: hasPause -->
     <!-- ko if: hasPause -->
-    <button class="btn" title="${ _('Suspend selected') }" data-bind="click: function() { control('resume'); }, enable: pauseEnabled">
+    <button class="btn" title="${ _('Suspend selected') }" data-bind="click: function() { control('suspend'); }, enable: pauseEnabled">
       <i class="fa fa-pause"></i> ${ _('Suspend') }
       <i class="fa fa-pause"></i> ${ _('Suspend') }
     </button>
     </button>
     <!-- /ko -->
     <!-- /ko -->
@@ -712,7 +698,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
     <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
     <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
   </div>
   </div>
 
 
-  <div data-bind="template: { name: 'actions' }"></div>
+  <div data-bind="template: { name: 'job-actions' }"></div>
 
 
   <ul class="nav nav-tabs margin-top-20">
   <ul class="nav nav-tabs margin-top-20">
     <li class="active"><a href="#workflow-page-graph" data-toggle="tab">${ _('Graph') }</a></li>
     <li class="active"><a href="#workflow-page-graph" data-toggle="tab">${ _('Graph') }</a></li>
@@ -816,9 +802,7 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
     <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
     <div class="bar" data-bind="style: {'width': progress() + '%'}"></div>
   </div>
   </div>
 
 
-  <a href="javascript:void(0)" data-bind="click: function() { control('kill'); }">${ _('Stop') }</a> |
-  <a href="javascript:void(0)" data-bind="click: function() { control('resume'); }">${ _('Resume')}</a> |
-  <a href="javascript:void(0)" data-bind="click: function() { control('rerun'); }">${ _('Rerun') }</a>
+  <div data-bind="template: { name: 'job-actions' }"></div>
 
 
   <br>
   <br>
 
 
@@ -840,6 +824,16 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
     </div>
     </div>
 
 
     <div class="tab-pane" id="schedule-page-tasks">
     <div class="tab-pane" id="schedule-page-tasks">
+      <div data-bind="template: { name: 'job-actions' }"></div>
+      
+      ${_('Filter')} <input type="text" class="input-xlarge search-query"  placeholder="${_('Filter by id, name, user...')}" />
+      <div class="btn-group">
+        <select size="3" multiple="true"></select>
+        <a class="btn btn-status btn-success" data-value="completed">${ _('Succeeded') }</a>
+        <a class="btn btn-status btn-warning" data-value="running">${ _('Running') }</a>
+        <a class="btn btn-status btn-danger disable-feedback" data-value="failed">${ _('Failed') }</a>
+      </div>
+    
       <table id="jobsTable" class="datatables table table-condensed">
       <table id="jobsTable" class="datatables table table-condensed">
         <thead>
         <thead>
         <tr>
         <tr>
@@ -1033,31 +1027,31 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
       self.properties = ko.mapping.fromJS(job.properties || {});
       self.properties = ko.mapping.fromJS(job.properties || {});
       self.mainType = ko.observable(vm.interface());
       self.mainType = ko.observable(vm.interface());
 
 
-      self.hasKill = ko.computed(function() {
-        return ['MAPREDUCE', 'SPARK', 'workflow'].indexOf(self.type()) != -1;
+      self.hasKill = ko.pureComputed(function() {
+        return ['MAPREDUCE', 'SPARK', 'workflow', 'schedule'].indexOf(self.type()) != -1;
       });
       });
-      self.killEnabled = ko.computed(function() {
+      self.killEnabled = ko.pureComputed(function() {
         return self.hasKill() && self.apiStatus() == 'RUNNING';
         return self.hasKill() && self.apiStatus() == 'RUNNING';
       });
       });
 
 
-      self.hasResume = ko.computed(function() {
-        return ['workflow'].indexOf(self.type()) != -1;
+      self.hasResume = ko.pureComputed(function() {
+        return ['workflow', 'schedule'].indexOf(self.type()) != -1;
       });
       });
-      self.resumeEnabled = ko.computed(function() {
+      self.resumeEnabled = ko.pureComputed(function() {
         return self.hasResume() && self.apiStatus() == 'PAUSED';
         return self.hasResume() && self.apiStatus() == 'PAUSED';
       });
       });
 
 
-      self.hasRerun = ko.computed(function() {
+      self.hasRerun = ko.pureComputed(function() {
         return ['workflow'].indexOf(self.type()) != -1;
         return ['workflow'].indexOf(self.type()) != -1;
       });
       });
-      self.rerunEnabled = ko.computed(function() {
+      self.rerunEnabled = ko.pureComputed(function() {
         return self.hasRerun() && ! self.isRunning();
         return self.hasRerun() && ! self.isRunning();
       });
       });
 
 
-      self.hasPause = ko.computed(function() {
-        return ['workflow'].indexOf(self.type()) != -1;
+      self.hasPause = ko.pureComputed(function() {
+        return ['workflow', 'schedule'].indexOf(self.type()) != -1;
       });
       });
-      self.pauseEnabled = ko.computed(function() {
+      self.pauseEnabled = ko.pureComputed(function() {
         return self.hasPause() && self.apiStatus() == 'RUNNING';
         return self.hasPause() && self.apiStatus() == 'RUNNING';
       });
       });
 
 
@@ -1279,37 +1273,37 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
       self.loadingJobs = ko.observable(false);
       self.loadingJobs = ko.observable(false);
       self.selectedJobs = ko.observableArray();
       self.selectedJobs = ko.observableArray();
 
 
-      self.hasKill = ko.computed(function() {
+      self.hasKill = ko.pureComputed(function() {
         return ['jobs', 'workflows'].indexOf(vm.interface()) != -1;
         return ['jobs', 'workflows'].indexOf(vm.interface()) != -1;
       });
       });
-      self.killEnabled = ko.computed(function() {
+      self.killEnabled = ko.pureComputed(function() {
         return self.hasKill() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
         return self.hasKill() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
           return job.killEnabled();
           return job.killEnabled();
         }).length == self.selectedJobs().length;
         }).length == self.selectedJobs().length;
       });
       });
 
 
-      self.hasResume = ko.computed(function() {
+      self.hasResume = ko.pureComputed(function() {
         return ['workflows'].indexOf(vm.interface()) != -1;
         return ['workflows'].indexOf(vm.interface()) != -1;
       });
       });
-      self.resumeEnabled = ko.computed(function() {
+      self.resumeEnabled = ko.pureComputed(function() {
         return self.hasResume() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
         return self.hasResume() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
           return job.resumeEnabled();
           return job.resumeEnabled();
         }).length == self.selectedJobs().length;
         }).length == self.selectedJobs().length;
       });
       });
 
 
-      self.hasRerun = ko.computed(function() {
+      self.hasRerun = ko.pureComputed(function() {
         return ['workflows'].indexOf(vm.interface()) != -1;
         return ['workflows'].indexOf(vm.interface()) != -1;
       });
       });
-      self.rerunEnabled = ko.computed(function() {
+      self.rerunEnabled = ko.pureComputed(function() {
         return self.hasRerun() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
         return self.hasRerun() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
           return job.hasRerun();
           return job.hasRerun();
         }).length == self.selectedJobs().length;
         }).length == self.selectedJobs().length;
       });
       });
 
 
-      self.hasPause = ko.computed(function() {
+      self.hasPause = ko.pureComputed(function() {
         return ['workflows'].indexOf(vm.interface()) != -1;
         return ['workflows'].indexOf(vm.interface()) != -1;
       });
       });
-      self.pauseEnabled = ko.computed(function() {
+      self.pauseEnabled = ko.pureComputed(function() {
         return self.hasPause() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
         return self.hasPause() && self.selectedJobs().length > 0 && $.grep(self.selectedJobs(), function(job) {
           return job.pauseEnabled();
           return job.pauseEnabled();
         }).length == self.selectedJobs().length;
         }).length == self.selectedJobs().length;