diff --git a/awx/ui/client/src/helpers/JobDetail.js b/awx/ui/client/src/helpers/JobDetail.js
index 0c6ea3359c..4911981939 100644
--- a/awx/ui/client/src/helpers/JobDetail.js
+++ b/awx/ui/client/src/helpers/JobDetail.js
@@ -930,7 +930,7 @@ export default
}])
// Call when the selected task needs to change
- .factory('SelectTask', ['LoadHosts', 'JobDetailService', function(LoadHosts, JobDetailService) {
+ .factory('SelectTask', ['JobDetailService', function(JobDetailService) {
return function(params) {
var scope = params.scope,
id = params.id,
@@ -953,111 +953,12 @@ export default
order: 'host_name,counter',
};
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
- scope.hostResults = JobDetailService.processHostResults(res.results)
+ scope.hostResults = JobDetailService.processHostEvents(res.results)
scope.hostResultsLoading = false;
});
};
}])
- // Refresh the list of hosts
- .factory('LoadHosts', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
- return function(params) {
- var scope = params.scope,
- callback = params.callback,
- url;
- scope.hostResults = [];
-
- if (scope.selectedTask) {
- // If we have a selected task, then get the list of hosts
- url = scope.job.related.job_events + '?parent=' + scope.selectedTask + '&';
- url += (scope.search_host_name) ? 'host__name__icontains=' + scope.search_host_name + '&' : '';
- url += (scope.search_host_status === 'failed') ? 'failed=true&' : '';
- url += 'event__startswith=runner&page_size=' + scope.hostResultsMaxRows + '&order=host_name,counter';
- console.log(url)
- scope.hostResultsLoading = true;
- Rest.setUrl(url);
- Rest.get()
- .success(function(data) {
- scope.next_host_results = data.next;
- scope.hostResults = [];
- data.results.forEach(function(event) {
- var status, status_text, item, msg;
- if (event.event === "runner_on_skipped") {
- status = 'skipped';
- }
- else if (event.event === "runner_on_unreachable") {
- status = 'unreachable';
- }
- else {
- status = (event.failed) ? 'failed' : (event.changed) ? 'changed' : 'successful';
- }
- switch(status) {
- case "successful":
- status_text = 'OK';
- break;
- case "changed":
- status_text = "Changed";
- break;
- case "failed":
- status_text = "Failed";
- break;
- case "unreachable":
- status_text = "Unreachable";
- break;
- case "skipped":
- status_text = "Skipped";
- }
-
- if (event.event_data && event.event_data.res) {
- item = event.event_data.res.item;
- if (typeof item === "object") {
- item = JSON.stringify(item);
- item = item.replace(/\"/g,'').replace(/:/g,': ').replace(/,/g,', ');
- }
- }
-
- msg = '';
- if (event.event_data && event.event_data.res) {
- if (typeof event.event_data.res === 'object') {
- msg = event.event_data.res.msg;
- } else {
- msg = event.event_data.res;
- }
- }
- if (event.event !== "runner_on_no_hosts") {
- scope.hostResults.push({
- id: event.id,
- status: status,
- status_text: status_text,
- host_id: event.host,
- task_id: event.parent,
- name: event.event_data.host,
- created: event.created,
- msg: msg,
- item: item
- });
- }
- });
-
- scope.hostResultsLoading = false;
- if (callback) {
- scope.$emit(callback);
- }
- })
- .error(function(data, status) {
- ProcessErrors(scope, data, status, null, { hdr: 'Error!',
- msg: 'Call to ' + url + '. GET returned: ' + status });
- });
- }
- else {
- if (callback) {
- scope.$emit(callback);
- }
- //$('#hosts-table-detail').mCustomScrollbar("update");
- }
- };
- }])
-
// Refresh the list of hosts in the hosts summary section
.factory('ReloadHostSummaryList', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
return function(params) {
@@ -1069,7 +970,6 @@ export default
url += (scope.search_host_summary_name) ? 'host_name__icontains=' + scope.search_host_summary_name + '&': '';
url += (scope.search_host_summary_status === 'failed') ? 'failed=true&' : '';
url += '&page_size=' + scope.hostSummariesMaxRows + '&order=host_name';
-
scope.hosts = [];
scope.hostSummariesLoading = true;
@@ -1098,7 +998,6 @@ export default
});
scope.hostSummariesLoading = false;
-
if (callback) {
scope.$emit(callback);
}
@@ -1564,7 +1463,6 @@ export default
function(DrawPlays, DrawTasks, DrawHostResults, DrawHostSummaries, DrawGraph) {
return function(params) {
var scope = params.scope;
-
if (!scope.pauseLiveEvents) {
DrawPlays({ scope: scope });
DrawTasks({ scope: scope });
diff --git a/awx/ui/client/src/helpers/JobSubmission.js b/awx/ui/client/src/helpers/JobSubmission.js
index aee3570311..37caa00329 100644
--- a/awx/ui/client/src/helpers/JobSubmission.js
+++ b/awx/ui/client/src/helpers/JobSubmission.js
@@ -804,6 +804,7 @@ function($compile, Rest, GetBasePath, TextareaResize,CreateDialog, GenerateForm,
if((scope.portalMode===false || scope.$parent.portalMode===false ) && Empty(data.system_job) ||
(base === 'home')){
$location.path('/jobs/' + job);
+ // use $state.go with reload: true option to re-instantiate sockets in
}
});
diff --git a/awx/ui/client/src/job-detail/host-event/host-event.route.js b/awx/ui/client/src/job-detail/host-event/host-event.route.js
index 7d4f1cc011..1d270039ab 100644
--- a/awx/ui/client/src/job-detail/host-event/host-event.route.js
+++ b/awx/ui/client/src/job-detail/host-event/host-event.route.js
@@ -35,19 +35,14 @@ var hostEventModal = {
$('.modal-backdrop').remove();
$('body').removeClass('modal-open');
}
- }
+ };
var hostEventDetails = {
name: 'jobDetail.host-event.details',
url: '/details',
controller: 'HostEventController',
templateUrl: templateUrl('job-detail/host-event/host-event-details'),
- resolve: {
- features: ['FeaturesService', function(FeaturesService){
- return FeaturesService.get();
- }]
- }
- }
+ };
var hostEventJson = {
name: 'jobDetail.host-event.json',
@@ -60,27 +55,12 @@ var hostEventModal = {
}]
}
};
- var hostEventTiming = {
- name: 'jobDetail.host-event.timing',
- url: '/timing',
- controller: 'HostEventController',
- templateUrl: templateUrl('job-detail/host-event/host-event-timing'),
- resolve: {
- features: ['FeaturesService', function(FeaturesService){
- return FeaturesService.get();
- }]
- }
- };
+
var hostEventStdout = {
name: 'jobDetail.host-event.stdout',
url: '/stdout',
controller: 'HostEventController',
- templateUrl: templateUrl('job-detail/host-event/host-event-stdout'),
- resolve: {
- features: ['FeaturesService', function(FeaturesService){
- return FeaturesService.get();
- }]
- }
+ templateUrl: templateUrl('job-detail/host-event/host-event-stdout')
};
- export {hostEventDetails, hostEventJson, hostEventTiming, hostEventStdout, hostEventModal}
\ No newline at end of file
+ export {hostEventDetails, hostEventJson, hostEventStdout, hostEventModal}
\ No newline at end of file
diff --git a/awx/ui/client/src/job-detail/host-event/main.js b/awx/ui/client/src/job-detail/host-event/main.js
index c2b82530a1..0670181f09 100644
--- a/awx/ui/client/src/job-detail/host-event/main.js
+++ b/awx/ui/client/src/job-detail/host-event/main.js
@@ -4,7 +4,7 @@
* All Rights Reserved
*************************************************/
- import {hostEventModal, hostEventDetails, hostEventTiming,
+ import {hostEventModal, hostEventDetails,
hostEventJson, hostEventStdout} from './host-event.route';
import controller from './host-event.controller';
@@ -15,7 +15,6 @@
.run(['$stateExtender', function($stateExtender){
$stateExtender.addState(hostEventModal);
$stateExtender.addState(hostEventDetails);
- $stateExtender.addState(hostEventTiming);
$stateExtender.addState(hostEventJson);
$stateExtender.addState(hostEventStdout);
}]);
\ No newline at end of file
diff --git a/awx/ui/client/src/job-detail/host-summary/host-summary-factory.js b/awx/ui/client/src/job-detail/host-summary/host-summary-factory.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/awx/ui/client/src/job-detail/host-summary/host-summary.controller.js b/awx/ui/client/src/job-detail/host-summary/host-summary.controller.js
new file mode 100644
index 0000000000..2af1b81443
--- /dev/null
+++ b/awx/ui/client/src/job-detail/host-summary/host-summary.controller.js
@@ -0,0 +1,53 @@
+/*************************************************
+ * Copyright (c) 2016 Ansible, Inc.
+ *
+ * All Rights Reserved
+ *************************************************/
+
+ export default
+ ['$scope', '$rootScope', '$stateParams', 'JobDetailService', 'jobSocket', function($scope, $rootScope, $stateParams, JobDetailService, jobSocket){
+
+ // the job_events socket should be substituted for a job_host_summary socket post 3.0
+ var page_size = 200;
+ var socketListener = function(){
+ console.log(jobSocket)
+ jobSocket.on('summary_complete', function(data) {
+ JobDetailService.getJob($stateParams.id).success(function(res){
+ console.log('job at summary_complete.', res)
+ });
+ });
+ jobSocket.on('status_changed', function(data) {
+ JobDetailService.getJob($stateParams.id).success(function(res){
+ console.log('job at data.stats.', data.status, res)
+ });
+ JobDetailService.getJobHostSummaries($stateParams.id, {}).success(function(res){
+ console.log('jobhostSummaries at summary_complete.', data.status, res)
+ });
+ });
+ }
+ $scope.loading = $scope.hosts.length > 0 ? false : true;
+ $scope.done = true;
+ $scope.events = [];
+ $scope.$watchCollection('events', function(c){
+ var filtered = $scope.events.filter(function(event){
+ return ((event.failed || event.changed ||
+ 'runner_on_ok' || 'runner_on_async_ok' ||
+ 'runner_on_unreachable' || 'runner_on_skipped')
+ && event.host_name != '');
+ });
+ var grouped = _.groupBy(filtered, 'host_name');
+ //$scope.hosts =
+ });
+
+
+ $scope.search = function(host_name){};
+ $scope.filter = function(filter){};
+
+ var init = function(){
+ socketListener();
+ JobDetailService.getJobHostSummaries($stateParams.id, {}).success(function(res){
+ console.log('jobhostSummaries at init.', res)
+ });
+ };
+ init();
+ }];
\ No newline at end of file
diff --git a/awx/ui/client/src/job-detail/host-summary/host-summary.partial.html b/awx/ui/client/src/job-detail/host-summary/host-summary.partial.html
new file mode 100644
index 0000000000..d86c5b3545
--- /dev/null
+++ b/awx/ui/client/src/job-detail/host-summary/host-summary.partial.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
diff --git a/awx/ui/client/src/job-detail/job-detail.controller.js b/awx/ui/client/src/job-detail/job-detail.controller.js
index 91264dd1b4..cbedbde7cb 100644
--- a/awx/ui/client/src/job-detail/job-detail.controller.js
+++ b/awx/ui/client/src/job-detail/job-detail.controller.js
@@ -277,7 +277,6 @@ export default
scope.$emit('LoadHostSummaries');
});
-
if (scope.removeInitialLoadComplete) {
scope.removeInitialLoadComplete();
}
@@ -292,12 +291,10 @@ export default
};
JobDetailService.getRelatedJobEvents(scope.job.id, params)
.success(function(data) {
- if (data.results.length > 0) {
LoadHostSummary({
scope: scope,
data: data.results[0].event_data
});
- }
UpdateDOM({ scope: scope });
})
.error(function(data, status) {
@@ -379,33 +376,12 @@ export default
};
JobDetailService.getRelatedJobEvents(scope.job.id, params)
.success(function(data) {
- console.log(data)
var idx, event, status, status_text, item, msg;
if (data.results.length > 0) {$
lastEventId = data.results[0].id;
}
scope.next_host_results = data.next;
- for (idx=data.results.length - 1; idx >= 0; idx--) {
- event = data.results[idx];
- event.status = JobDetailService.processEventStatus(event).status;
- msg = JobDetailService.processEventMsg(event);
- item = JobDetailService.processEventItem(event);
-
- if (event.event !== "runner_on$_no_hosts") {
- task.hostResults[event.id] = {
- id: event.id,
- status: event.status,
- status_text: event.status.toUpperCase(),
- host_id: event.host,
- task_id: event.parent,
- name: event.event_data.host,
- created: event.created,
- msg: msg,
- counter: event.counter,
- item: item
- };
- }
- }
+ task.hostResults = JobDetailService.processHostEvents(data.results);
scope.$emit('LoadHostSummaries');
});
} else {
@@ -999,13 +975,6 @@ export default
scope.searchTasksEnabled = true;
}
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
- // /api/v1/jobs/15/job_tasks/?event_id=762&task__icontains=create&page_size=200&order=id
- var params = {
- event_id: scope.selectedPlay,
- task__icontains: scope.search_task_name,
- page_size: scope.tasksMaxRows,
-
- };
if (scope.search_task_status === 'failed'){
params.failed = true;
}
@@ -1042,7 +1011,7 @@ export default
params.failed = true;
}
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
- scope.hostResults = JobDetailService.processHostResults(res.results)
+ scope.hostResults = JobDetailService.processHostEvents(res.results)
scope.hostResultsLoading = false;
});
}
@@ -1088,7 +1057,6 @@ export default
scope.filterHostStatus = function() {
scope.search_host_status = (scope.search_host_status === 'all') ? 'failed' : 'all';
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
- console.log('filterHostStattus', scope)
var params = {
parent: scope.selectedTask,
event__startswith: 'runner',
@@ -1100,7 +1068,7 @@ export default
}
scope.hostResultsLoading = true;
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
- scope.hostResults = JobDetailService.processHostResults(res.results)
+ scope.hostResults = JobDetailService.processHostEvents(res.results)
scope.hostResultsLoading = false;
});
}
@@ -1109,6 +1077,21 @@ export default
scope.filterHostSummaryStatus = function() {
scope.search_host_summary_status = (scope.search_host_summary_status === 'all') ? 'failed' : 'all';
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
+ // /api/v1/jobs/11/job_host_summaries/?failed=true&&page_size=200&order=host_name
+ var params = {
+ page_size: scope.hostSummariesMaxRows,
+ order: 'host_name'
+ }
+ if (scope.search_host_summary_status === 'failed'){
+ params.failed = true;
+ }
+ /*
+ JobDetailService.getJobHostSummaries(scope.job.id, params).success(function(res){
+ scope.next_host_summaries = res.next;
+ scope.hosts = res.results;
+ console.log(res.results)
+ });
+ */
ReloadHostSummaryList({
scope: scope
});
diff --git a/awx/ui/client/src/job-detail/job-detail.partial.html b/awx/ui/client/src/job-detail/job-detail.partial.html
index 2ced4bf551..616b463386 100644
--- a/awx/ui/client/src/job-detail/job-detail.partial.html
+++ b/awx/ui/client/src/job-detail/job-detail.partial.html
@@ -388,75 +388,10 @@
-
-
+
+
diff --git a/awx/ui/client/src/job-detail/job-detail.route.js b/awx/ui/client/src/job-detail/job-detail.route.js
index 3494845759..62678016fe 100644
--- a/awx/ui/client/src/job-detail/job-detail.route.js
+++ b/awx/ui/client/src/job-detail/job-detail.route.js
@@ -5,12 +5,11 @@
*************************************************/
import {templateUrl} from '../shared/template-url/template-url.factory';
+import HostSummaryController from './host-summary/host-summary.controller';
export default {
name: 'jobDetail',
url: '/jobs/:id',
- templateUrl: templateUrl('job-detail/job-detail'),
- controller: 'JobDetailController',
ncyBreadcrumb: {
parent: 'jobs',
label: "{{ job.id }} - {{ job.name }}"
@@ -26,10 +25,32 @@ export default {
endpoint: "job_events"
});
$rootScope.event_socket.init();
+ // returns should really be providing $rootScope.event_socket
+ // otherwise, we have to inject the entire $rootScope into the controller
return true;
} else {
return true;
}
+ }],
+ jobSocket: ['Socket', '$rootScope', function(Socket, $rootScope) {
+ var job_socket = Socket({
+ scope: $rootScope,
+ endpoint: "jobs"
+ });
+ job_socket.init();
+ // returns should really be providing $rootScope.job_socket
+ // otherwise, we have to inject the entire $rootScope into the controller
+ return job_socket;
}]
+ },
+ views: {
+ '': {
+ templateUrl: templateUrl('job-detail/job-detail'),
+ controller: 'JobDetailController',
+ },
+ 'host-summary@jobDetail': {
+ templateUrl: templateUrl('job-detail/host-summary/host-summary'),
+ controller: HostSummaryController
+ }
}
};
diff --git a/awx/ui/client/src/job-detail/job-detail.service.js b/awx/ui/client/src/job-detail/job-detail.service.js
index 2beecdc215..640aa4def7 100644
--- a/awx/ui/client/src/job-detail/job-detail.service.js
+++ b/awx/ui/client/src/job-detail/job-detail.service.js
@@ -63,52 +63,47 @@ export default
// the stack for which status to display is
// unreachable > failed > changed > ok
// uses the API's runner events and convenience properties .failed .changed to determine status.
- // see: job_event_callback.py
+ // see: job_event_callback.py for more filters to support
processEventStatus: function(event){
- if (event.event == 'runner_on_unreachable'){
- return {
- class: 'HostEvents-status--unreachable',
- status: 'unreachable'
- }
+ if (event.event == 'runner_on_unreachable'){
+ return {
+ class: 'HostEvents-status--unreachable',
+ status: 'unreachable'
}
- // equiv to 'runner_on_error' && 'runner on failed'
- if (event.failed){
- return {
- class: 'HostEvents-status--failed',
- status: 'failed'
- }
+ }
+ // equiv to 'runner_on_error' && 'runner on failed'
+ if (event.failed){
+ return {
+ class: 'HostEvents-status--failed',
+ status: 'failed'
}
- // catch the changed case before ok, because both can be true
- if (event.changed){
- return {
- class: 'HostEvents-status--changed',
- status: 'changed'
- }
+ }
+ // catch the changed case before ok, because both can be true
+ if (event.changed){
+ return {
+ class: 'HostEvents-status--changed',
+ status: 'changed'
}
- if (event.event == 'runner_on_ok'){
- return {
- class: 'HostEvents-status--ok',
- status: 'ok'
- }
+ }
+ if (event.event == 'runner_on_ok' || event.event == 'runner_on_async_ok'){
+ return {
+ class: 'HostEvents-status--ok',
+ status: 'ok'
}
- if (event.event == 'runner_on_skipped'){
- return {
- class: 'HostEvents-status--skipped',
- status: 'skipped'
- }
- }
- else{
- // study a case where none of these apply
+ }
+ if (event.event == 'runner_on_skipped'){
+ return {
+ class: 'HostEvents-status--skipped',
+ status: 'skipped'
}
+ }
},
-
- // Consumes a response from this.getRelatedJobEvents
+ // Consumes a response from this.getRelatedJobEvents(id, params)
// returns an array for view logic to iterate over to build host result rows
- processHostResults: function(data){
+ processHostEvents: function(data){
var self = this;
var results = [];
- data.forEach(function(element, index, array){
- var event = element;
+ data.forEach(function(event){
if (event.event !== 'runner_on_no_hosts'){
var status = self.processEventStatus(event);
var msg = self.processEventMsg(event);
@@ -116,7 +111,7 @@ export default
results.push({
id: event.id,
status: status.status,
- status_text: status.status.charAt(0).toUpperCase() + status.status.slice(1),
+ status_text: _.head(status.status).toUpperCase() + _.tail(status.status),
host_id: event.host,
task_id: event.parent,
name: event.event_data.host,
@@ -128,7 +123,6 @@ export default
});
return results;
},
-
// GET events related to a job run
// e.g.
// ?event=playbook_on_stats