mirror of
https://github.com/ansible/awx.git
synced 2026-02-28 00:08:44 -03:30
job results cleanup 1 of 2
This commit is contained in:
committed by
jaredevantabor
parent
f3526ca86c
commit
53d7a822bd
@@ -7,162 +7,155 @@
|
|||||||
export default ['jobResultsService', 'parseStdoutService', '$q', function(jobResultsService, parseStdoutService, $q){
|
export default ['jobResultsService', 'parseStdoutService', '$q', function(jobResultsService, parseStdoutService, $q){
|
||||||
var val = {};
|
var val = {};
|
||||||
|
|
||||||
// Get the count of the last event
|
|
||||||
var getPreviousCount = function(counter, type) {
|
|
||||||
var countAttr;
|
|
||||||
|
|
||||||
if (type === 'play') {
|
|
||||||
countAttr = 'playCount';
|
|
||||||
} else if (type === 'task') {
|
|
||||||
countAttr = 'taskCount';
|
|
||||||
} else {
|
|
||||||
countAttr = 'count';
|
|
||||||
}
|
|
||||||
|
|
||||||
var previousCount = $q.defer();
|
|
||||||
|
|
||||||
// iteratively find the last count
|
|
||||||
var findCount = function(counter) {
|
|
||||||
if (counter === 0) {
|
|
||||||
// if counter is 0, no count has been initialized
|
|
||||||
// initialize one!
|
|
||||||
|
|
||||||
if (countAttr === 'count') {
|
|
||||||
previousCount.resolve({
|
|
||||||
ok: 0,
|
|
||||||
skipped: 0,
|
|
||||||
unreachable: 0,
|
|
||||||
failures: 0,
|
|
||||||
changed: 0
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
previousCount.resolve(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (val.queue[counter] && val.queue[counter][countAttr] !== undefined) {
|
|
||||||
// this event has a count, resolve!
|
|
||||||
previousCount.resolve(_.clone(val.queue[counter][countAttr]));
|
|
||||||
} else {
|
|
||||||
// this event doesn't have a count, decrement to the
|
|
||||||
// previous event and check it
|
|
||||||
findCount(counter - 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (val.queue[counter - 1]) {
|
|
||||||
// if the previous event has been resolved, start the iterative
|
|
||||||
// get previous count process
|
|
||||||
findCount(counter - 1);
|
|
||||||
} else if (val.populateDefers[counter - 1]){
|
|
||||||
// if the previous event has not been resolved, wait for it to
|
|
||||||
// be and then start the iterative get previous count process
|
|
||||||
val.populateDefers[counter - 1].promise.then(function() {
|
|
||||||
findCount(counter - 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return previousCount.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
// munge the raw event from the backend into the event_queue's format
|
|
||||||
var mungeEvent = function(event) {
|
|
||||||
var mungedEventDefer = $q.defer();
|
|
||||||
|
|
||||||
// basic data needed in the munged event
|
|
||||||
var mungedEvent = {
|
|
||||||
counter: event.counter,
|
|
||||||
id: event.id,
|
|
||||||
processed: false,
|
|
||||||
name: event.event_name,
|
|
||||||
changes: []
|
|
||||||
};
|
|
||||||
|
|
||||||
// the interface for grabbing standard out is generalized and
|
|
||||||
// present across many types of events, so go ahead and check for
|
|
||||||
// updates to it
|
|
||||||
if (event.stdout) {
|
|
||||||
mungedEvent.stdout = parseStdoutService.parseStdout(event);
|
|
||||||
mungedEvent.changes.push('stdout');
|
|
||||||
}
|
|
||||||
|
|
||||||
// for different types of events, you need different types of data
|
|
||||||
if (event.event_name === 'playbook_on_start') {
|
|
||||||
mungedEvent.count = {
|
|
||||||
ok: 0,
|
|
||||||
skipped: 0,
|
|
||||||
unreachable: 0,
|
|
||||||
failures: 0,
|
|
||||||
changed: 0
|
|
||||||
};
|
|
||||||
mungedEvent.startTime = event.modified;
|
|
||||||
mungedEvent.changes.push('count');
|
|
||||||
mungedEvent.changes.push('startTime');
|
|
||||||
} else if (event.event_name === 'playbook_on_play_start') {
|
|
||||||
getPreviousCount(mungedEvent.counter, "play")
|
|
||||||
.then(count => {
|
|
||||||
mungedEvent.playCount = count + 1;
|
|
||||||
mungedEvent.changes.push('playCount');
|
|
||||||
});
|
|
||||||
} else if (event.event_name === 'playbook_on_task_start') {
|
|
||||||
getPreviousCount(mungedEvent.counter, "task")
|
|
||||||
.then(count => {
|
|
||||||
mungedEvent.taskCount = count + 1;
|
|
||||||
mungedEvent.changes.push('taskCount');
|
|
||||||
});
|
|
||||||
} else if (event.event_name === 'runner_on_ok' ||
|
|
||||||
event.event_name === 'runner_on_async_ok') {
|
|
||||||
getPreviousCount(mungedEvent.counter)
|
|
||||||
.then(count => {
|
|
||||||
mungedEvent.count = count;
|
|
||||||
mungedEvent.count.ok++;
|
|
||||||
mungedEvent.changes.push('count');
|
|
||||||
});
|
|
||||||
} else if (event.event_name === 'runner_on_skipped') {
|
|
||||||
getPreviousCount(mungedEvent.counter)
|
|
||||||
.then(count => {
|
|
||||||
mungedEvent.count = count;
|
|
||||||
mungedEvent.count.skipped++;
|
|
||||||
mungedEvent.changes.push('count');
|
|
||||||
});
|
|
||||||
} else if (event.event_name === 'runner_on_unreachable') {
|
|
||||||
getPreviousCount(mungedEvent.counter)
|
|
||||||
.then(count => {
|
|
||||||
mungedEvent.count = count;
|
|
||||||
mungedEvent.count.unreachable++;
|
|
||||||
mungedEvent.changes.push('count');
|
|
||||||
});
|
|
||||||
} else if (event.event_name === 'runner_on_error' ||
|
|
||||||
event.event_name === 'runner_on_async_failed') {
|
|
||||||
getPreviousCount(mungedEvent.counter)
|
|
||||||
.then(count => {
|
|
||||||
mungedEvent.count = count;
|
|
||||||
mungedEvent.count.failed++;
|
|
||||||
mungedEvent.changes.push('count');
|
|
||||||
});
|
|
||||||
} else if (event.event_name === 'playbook_on_stats') {
|
|
||||||
// get the data for populating the host status bar
|
|
||||||
mungedEvent.count = jobResultsService
|
|
||||||
.getCountsFromStatsEvent(event.event_data);
|
|
||||||
mungedEvent.finishedTime = event.modified;
|
|
||||||
mungedEvent.changes.push('count');
|
|
||||||
mungedEvent.changes.push('countFinished');
|
|
||||||
mungedEvent.changes.push('finishedTime');
|
|
||||||
}
|
|
||||||
|
|
||||||
mungedEventDefer.resolve(mungedEvent);
|
|
||||||
|
|
||||||
return mungedEventDefer.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
val = {
|
val = {
|
||||||
populateDefers: {},
|
populateDefers: {},
|
||||||
queue: {},
|
queue: {},
|
||||||
|
// Get the count of the last event
|
||||||
|
getPreviousCount: function(counter, type) {
|
||||||
|
var countAttr;
|
||||||
|
|
||||||
|
if (type === 'play') {
|
||||||
|
countAttr = 'playCount';
|
||||||
|
} else if (type === 'task') {
|
||||||
|
countAttr = 'taskCount';
|
||||||
|
} else {
|
||||||
|
countAttr = 'count';
|
||||||
|
}
|
||||||
|
|
||||||
|
var previousCount = $q.defer();
|
||||||
|
|
||||||
|
// iteratively find the last count
|
||||||
|
var findCount = function(counter) {
|
||||||
|
if (counter === 0) {
|
||||||
|
// if counter is 0, no count has been initialized
|
||||||
|
// initialize one!
|
||||||
|
|
||||||
|
if (countAttr === 'count') {
|
||||||
|
previousCount.resolve({
|
||||||
|
ok: 0,
|
||||||
|
skipped: 0,
|
||||||
|
unreachable: 0,
|
||||||
|
failures: 0,
|
||||||
|
changed: 0
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
previousCount.resolve(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (val.queue[counter] && val.queue[counter][countAttr] !== undefined) {
|
||||||
|
// this event has a count, resolve!
|
||||||
|
previousCount.resolve(_.clone(val.queue[counter][countAttr]));
|
||||||
|
} else {
|
||||||
|
// this event doesn't have a count, decrement to the
|
||||||
|
// previous event and check it
|
||||||
|
findCount(counter - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (val.queue[counter - 1]) {
|
||||||
|
// if the previous event has been resolved, start the iterative
|
||||||
|
// get previous count process
|
||||||
|
findCount(counter - 1);
|
||||||
|
} else if (val.populateDefers[counter - 1]){
|
||||||
|
// if the previous event has not been resolved, wait for it to
|
||||||
|
// be and then start the iterative get previous count process
|
||||||
|
val.populateDefers[counter - 1].promise.then(function() {
|
||||||
|
findCount(counter - 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return previousCount.promise;
|
||||||
|
},
|
||||||
|
// munge the raw event from the backend into the event_queue's format
|
||||||
|
munge: function(event) {
|
||||||
|
var mungedEventDefer = $q.defer();
|
||||||
|
|
||||||
|
// basic data needed in the munged event
|
||||||
|
var mungedEvent = {
|
||||||
|
counter: event.counter,
|
||||||
|
id: event.id,
|
||||||
|
processed: false,
|
||||||
|
name: event.event_name,
|
||||||
|
changes: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// the interface for grabbing standard out is generalized and
|
||||||
|
// present across many types of events, so go ahead and check for
|
||||||
|
// updates to it
|
||||||
|
if (event.stdout) {
|
||||||
|
mungedEvent.stdout = parseStdoutService.parseStdout(event);
|
||||||
|
mungedEvent.changes.push('stdout');
|
||||||
|
}
|
||||||
|
|
||||||
|
// for different types of events, you need different types of data
|
||||||
|
if (event.event_name === 'playbook_on_start') {
|
||||||
|
mungedEvent.count = {
|
||||||
|
ok: 0,
|
||||||
|
skipped: 0,
|
||||||
|
unreachable: 0,
|
||||||
|
failures: 0,
|
||||||
|
changed: 0
|
||||||
|
};
|
||||||
|
mungedEvent.startTime = event.modified;
|
||||||
|
mungedEvent.changes.push('count');
|
||||||
|
mungedEvent.changes.push('startTime');
|
||||||
|
} else if (event.event_name === 'playbook_on_play_start') {
|
||||||
|
val.getPreviousCount(mungedEvent.counter, "play")
|
||||||
|
.then(count => {
|
||||||
|
mungedEvent.playCount = count + 1;
|
||||||
|
mungedEvent.changes.push('playCount');
|
||||||
|
});
|
||||||
|
} else if (event.event_name === 'playbook_on_task_start') {
|
||||||
|
val.getPreviousCount(mungedEvent.counter, "task")
|
||||||
|
.then(count => {
|
||||||
|
mungedEvent.taskCount = count + 1;
|
||||||
|
mungedEvent.changes.push('taskCount');
|
||||||
|
});
|
||||||
|
} else if (event.event_name === 'runner_on_ok' ||
|
||||||
|
event.event_name === 'runner_on_async_ok') {
|
||||||
|
val.getPreviousCount(mungedEvent.counter)
|
||||||
|
.then(count => {
|
||||||
|
mungedEvent.count = count;
|
||||||
|
mungedEvent.count.ok++;
|
||||||
|
mungedEvent.changes.push('count');
|
||||||
|
});
|
||||||
|
} else if (event.event_name === 'runner_on_skipped') {
|
||||||
|
val.getPreviousCount(mungedEvent.counter)
|
||||||
|
.then(count => {
|
||||||
|
mungedEvent.count = count;
|
||||||
|
mungedEvent.count.skipped++;
|
||||||
|
mungedEvent.changes.push('count');
|
||||||
|
});
|
||||||
|
} else if (event.event_name === 'runner_on_unreachable') {
|
||||||
|
val.getPreviousCount(mungedEvent.counter)
|
||||||
|
.then(count => {
|
||||||
|
mungedEvent.count = count;
|
||||||
|
mungedEvent.count.unreachable++;
|
||||||
|
mungedEvent.changes.push('count');
|
||||||
|
});
|
||||||
|
} else if (event.event_name === 'runner_on_error' ||
|
||||||
|
event.event_name === 'runner_on_async_failed') {
|
||||||
|
val.getPreviousCount(mungedEvent.counter)
|
||||||
|
.then(count => {
|
||||||
|
mungedEvent.count = count;
|
||||||
|
mungedEvent.count.failed++;
|
||||||
|
mungedEvent.changes.push('count');
|
||||||
|
});
|
||||||
|
} else if (event.event_name === 'playbook_on_stats') {
|
||||||
|
// get the data for populating the host status bar
|
||||||
|
mungedEvent.count = jobResultsService
|
||||||
|
.getCountsFromStatsEvent(event.event_data);
|
||||||
|
mungedEvent.finishedTime = event.modified;
|
||||||
|
mungedEvent.changes.push('count');
|
||||||
|
mungedEvent.changes.push('countFinished');
|
||||||
|
mungedEvent.changes.push('finishedTime');
|
||||||
|
}
|
||||||
|
|
||||||
|
mungedEventDefer.resolve(mungedEvent);
|
||||||
|
|
||||||
|
return mungedEventDefer.promise;
|
||||||
|
},
|
||||||
// reinitializes the event queue value for the job results page
|
// reinitializes the event queue value for the job results page
|
||||||
//
|
|
||||||
// TODO: implement some sort of local storage scheme
|
|
||||||
// to make viewing job details that the user has
|
|
||||||
// previous clicked on super quick, this would be where you grab
|
|
||||||
// from local storage
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
val.queue = {};
|
val.queue = {};
|
||||||
val.populateDefers = {};
|
val.populateDefers = {};
|
||||||
@@ -175,6 +168,8 @@ export default ['jobResultsService', 'parseStdoutService', '$q', function(jobRes
|
|||||||
val.populateDefers[event.counter] = $q.defer();
|
val.populateDefers[event.counter] = $q.defer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure not to send duplicate events over to the
|
||||||
|
// controller
|
||||||
if (val.queue[event.counter] &&
|
if (val.queue[event.counter] &&
|
||||||
val.queue[event.counter].processed) {
|
val.queue[event.counter].processed) {
|
||||||
val.populateDefers.reject("duplicate event: " +
|
val.populateDefers.reject("duplicate event: " +
|
||||||
@@ -185,11 +180,6 @@ export default ['jobResultsService', 'parseStdoutService', '$q', function(jobRes
|
|||||||
var resolvePopulation = function(event) {
|
var resolvePopulation = function(event) {
|
||||||
// to resolve, put the event on the queue and
|
// to resolve, put the event on the queue and
|
||||||
// then resolve the deferred value
|
// then resolve the deferred value
|
||||||
//
|
|
||||||
// TODO: implement some sort of local storage scheme
|
|
||||||
// to make viewing job details that the user has
|
|
||||||
// previous clicked on super quick, this would be
|
|
||||||
// where you put in local storage
|
|
||||||
val.queue[event.counter] = event;
|
val.queue[event.counter] = event;
|
||||||
val.populateDefers[event.counter].resolve(event);
|
val.populateDefers[event.counter].resolve(event);
|
||||||
};
|
};
|
||||||
@@ -197,7 +187,7 @@ export default ['jobResultsService', 'parseStdoutService', '$q', function(jobRes
|
|||||||
if (event.counter === 1) {
|
if (event.counter === 1) {
|
||||||
// for the first event, go ahead and munge and
|
// for the first event, go ahead and munge and
|
||||||
// resolve
|
// resolve
|
||||||
mungeEvent(event).then(event => {
|
val.munge(event).then(event => {
|
||||||
resolvePopulation(event);
|
resolvePopulation(event);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -214,15 +204,11 @@ export default ['jobResultsService', 'parseStdoutService', '$q', function(jobRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// you can start the munging process...
|
// you can start the munging process...
|
||||||
mungeEvent(event).then(event => {
|
val.munge(event).then(event => {
|
||||||
// ...but wait until the previous event has
|
// ...but wait until the previous event has
|
||||||
// been resolved before resolving this one and
|
// been resolved before resolving this one and
|
||||||
// doing stuff in the ui (that's why we
|
// doing stuff in the ui (that's why we
|
||||||
// needed that previous conditional). this
|
// needed that previous conditional).
|
||||||
// could be done in a more asynchronous nature
|
|
||||||
// if we need a performance boost. See the
|
|
||||||
// todo note in the markProcessed function
|
|
||||||
// for an idea
|
|
||||||
val.populateDefers[event.counter - 1].promise
|
val.populateDefers[event.counter - 1].promise
|
||||||
.then(() => {
|
.then(() => {
|
||||||
resolvePopulation(event);
|
resolvePopulation(event);
|
||||||
@@ -245,19 +231,6 @@ export default ['jobResultsService', 'parseStdoutService', '$q', function(jobRes
|
|||||||
// the event has now done it's work in the UI, record
|
// the event has now done it's work in the UI, record
|
||||||
// that!
|
// that!
|
||||||
val.queue[event.counter].processed = true;
|
val.queue[event.counter].processed = true;
|
||||||
|
|
||||||
// TODO: we can actually record what has been done in the
|
|
||||||
// UI and at what event too! (something like "resolved
|
|
||||||
// the count on event 63)".
|
|
||||||
//
|
|
||||||
// if we do something like this, we actually wouldn't
|
|
||||||
// have to wait until the previous events had completed
|
|
||||||
// before resolving and returning to the controller
|
|
||||||
// in populate()...
|
|
||||||
// in other words, we could send events out of order to
|
|
||||||
// the controller, but let the controller know that it's
|
|
||||||
// an older event that what is in the view so we don't
|
|
||||||
// need to do anything
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!val.queue[event.counter]) {
|
if (!val.queue[event.counter]) {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
@import '../../shared/branding/colors.default.less';
|
@import '../../shared/branding/colors.default.less';
|
||||||
|
|
||||||
|
@breakpoint-md: 1200px;
|
||||||
|
|
||||||
.JobResultsStdOut {
|
.JobResultsStdOut {
|
||||||
height: ~"calc(100% - 70px)";
|
height: ~"calc(100% - 70px)";
|
||||||
}
|
}
|
||||||
@@ -204,7 +206,7 @@
|
|||||||
color: @default-interface-txt;
|
color: @default-interface-txt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1199px) {
|
@media (max-width: @breakpoint-md) {
|
||||||
.JobResultsStdOut-numberColumnPreload {
|
.JobResultsStdOut-numberColumnPreload {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
@import '../shared/layouts/one-plus-two.less';
|
@import '../shared/layouts/one-plus-two.less';
|
||||||
|
|
||||||
@breakpoint-md: 1200px;
|
@breakpoint-md: 1200px;
|
||||||
@breakpoint-sm: 623px;
|
|
||||||
|
|
||||||
.JobResults {
|
.JobResults {
|
||||||
.OnePlusTwo-container(100%, @breakpoint-md);
|
.OnePlusTwo-container(100%, @breakpoint-md);
|
||||||
@@ -115,7 +114,7 @@
|
|||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1199px) {
|
@media (max-width: @breakpoint-md) {
|
||||||
.JobResults-detailsPanel {
|
.JobResults-detailsPanel {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,14 +144,19 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count'
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(change === 'stdout'){
|
if(change === 'stdout'){
|
||||||
|
// put stdout elements in stdout container
|
||||||
angular
|
angular
|
||||||
.element(".JobResultsStdOut-stdoutContainer")
|
.element(".JobResultsStdOut-stdoutContainer")
|
||||||
.append($compile(mungedEvent
|
.append($compile(mungedEvent
|
||||||
.stdout)($scope));
|
.stdout)($scope));
|
||||||
|
|
||||||
|
// move the followAnchor to the bottom of the
|
||||||
|
// container
|
||||||
$(".JobResultsStdOut-followAnchor")
|
$(".JobResultsStdOut-followAnchor")
|
||||||
.appendTo(".JobResultsStdOut-stdoutContainer");
|
.appendTo(".JobResultsStdOut-stdoutContainer");
|
||||||
|
|
||||||
|
// if follow is engaged,
|
||||||
|
// scroll down to the followAnchor
|
||||||
if ($scope.followEngaged) {
|
if ($scope.followEngaged) {
|
||||||
$scope.followScroll();
|
$scope.followScroll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErr
|
|||||||
|
|
||||||
return count;
|
return count;
|
||||||
},
|
},
|
||||||
|
// rest call to grab previously complete job_events
|
||||||
getEvents: function(url) {
|
getEvents: function(url) {
|
||||||
var val = $q.defer();
|
var val = $q.defer();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user