mirror of
https://github.com/ansible/awx.git
synced 2026-04-14 06:29:25 -02:30
216 lines
9.2 KiB
JavaScript
216 lines
9.2 KiB
JavaScript
/*************************************************
|
|
* Copyright (c) 2016 Ansible, Inc.
|
|
*
|
|
* All Rights Reserved
|
|
*************************************************/
|
|
|
|
export default ['$log', '$rootScope', '$scope', '$state', '$stateParams', 'ProcessErrors', 'Rest', 'Wait',
|
|
function ($log, $rootScope, $scope, $state, $stateParams, ProcessErrors, Rest, Wait) {
|
|
|
|
var api_complete = false,
|
|
current_range,
|
|
loaded_sections = [],
|
|
event_queue = 0,
|
|
auto_scroll_down=true, // programmatic scroll to bottom
|
|
live_event_processing = true,
|
|
page_size = 500,
|
|
job_id = $stateParams.id;
|
|
|
|
$scope.should_apply_live_events = true;
|
|
|
|
// Open up a socket for events depending on the type of job
|
|
function openSockets() {
|
|
if ($state.current.name === 'jobDetail') {
|
|
$log.debug("socket watching on job_events-" + job_id);
|
|
$rootScope.$on(`ws-${$state.current.name}-job_events-${job_id}`, function() {
|
|
$log.debug("socket fired on job_events-" + job_id);
|
|
if (api_complete) {
|
|
event_queue++;
|
|
}
|
|
});
|
|
// Unbind $rootScope socket event binding(s) so that they don't get triggered
|
|
// in another instance of this controller
|
|
// $scope.$on('$destroy', function() {
|
|
// $rootScope.socket.removeAllListeners("job_events-" + job_id);
|
|
// });
|
|
}
|
|
if ($state.current.name === 'adHocJobStdout') {
|
|
$log.debug("socket watching on ad_hoc_command_events-" + job_id);
|
|
$rootScope.$on(`ws-${$state.current.name}-ad_hoc_command_events-${job_id}`, function() {
|
|
$log.debug("socket fired on ad_hoc_command_events-" + job_id);
|
|
if (api_complete) {
|
|
event_queue++;
|
|
}
|
|
});
|
|
// Unbind $rootScope socket event binding(s) so that they don't get triggered
|
|
// in another instance of this controller
|
|
// $scope.$on('$destroy', function() {
|
|
// $rootScope.adhoc_event_socket.removeAllListeners("ad_hoc_command_events-" + job_id);
|
|
// });
|
|
}
|
|
}
|
|
|
|
openSockets();
|
|
|
|
// This is a trigger for loading up the standard out
|
|
if ($scope.removeLoadStdout) {
|
|
$scope.removeLoadStdout();
|
|
}
|
|
$scope.removeLoadStdout = $scope.$on('LoadStdout', function() {
|
|
if (loaded_sections.length === 0) {
|
|
loadStdout();
|
|
}
|
|
else if (live_event_processing) {
|
|
getNextSection();
|
|
}
|
|
});
|
|
|
|
// This interval checks to see whether or not we've gotten a new
|
|
// event via sockets. If so, go out and update the standard out
|
|
// log.
|
|
$rootScope.jobStdOutInterval = setInterval( function() {
|
|
if (event_queue > 0) {
|
|
// events happened since the last check
|
|
$log.debug('checking for stdout...');
|
|
if (loaded_sections.length === 0) { ////this if statement for refresh
|
|
$log.debug('calling LoadStdout');
|
|
loadStdout();
|
|
}
|
|
else if (live_event_processing) {
|
|
$log.debug('calling getNextSection');
|
|
getNextSection();
|
|
}
|
|
event_queue = 0;
|
|
}
|
|
}, 2000);
|
|
|
|
// stdoutEndpoint gets passed through in the directive declaration.
|
|
// This watcher fires off loadStdout() when the endpoint becomes
|
|
// available.
|
|
$scope.$watch('stdoutEndpoint', function(newVal, oldVal) {
|
|
if(newVal && newVal !== oldVal) {
|
|
// Fire off the server call
|
|
loadStdout();
|
|
}
|
|
});
|
|
|
|
// stdoutText optionall gets passed through in the directive declaration.
|
|
$scope.$watch('stdoutText', function(newVal, oldVal) {
|
|
if(newVal && newVal !== oldVal) {
|
|
$('#pre-container-content').html(newVal);
|
|
}
|
|
});
|
|
|
|
function loadStdout() {
|
|
if (!$scope.stdoutEndpoint) {
|
|
return;
|
|
}
|
|
|
|
Rest.setUrl($scope.stdoutEndpoint + '?format=json&start_line=0&end_line=' + page_size);
|
|
Rest.get()
|
|
.success(function(data) {
|
|
Wait('stop');
|
|
if (data.content) {
|
|
api_complete = true;
|
|
$('#pre-container-content').html(data.content);
|
|
current_range = data.range;
|
|
if (data.content !== "Waiting for results...") {
|
|
loaded_sections.push({
|
|
start: (data.range.start < 0) ? 0 : data.range.start,
|
|
end: data.range.end
|
|
});
|
|
}
|
|
|
|
$('#pre-container').scrollTop($('#pre-container').prop("scrollHeight"));
|
|
}
|
|
else {
|
|
api_complete = true;
|
|
}
|
|
})
|
|
.error(function(data, status) {
|
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
|
msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
|
|
});
|
|
}
|
|
|
|
function getNextSection() {
|
|
if (!$scope.stdoutEndpoint) {
|
|
return;
|
|
}
|
|
|
|
// get the next range of data from the API
|
|
var start = loaded_sections[loaded_sections.length - 1].end, url;
|
|
url = $scope.stdoutEndpoint + '?format=json&start_line=' + start + '&end_line=' + (start + page_size);
|
|
$('#stdoutMoreRowsBottom').fadeIn();
|
|
Rest.setUrl(url);
|
|
Rest.get()
|
|
.success( function(data) {
|
|
if ($('#pre-container-content').html() === "Waiting for results...") {
|
|
$('#pre-container-content').html(data.content);
|
|
} else {
|
|
$('#pre-container-content').append(data.content);
|
|
}
|
|
loaded_sections.push({
|
|
start: (data.range.start < 0) ? 0 : data.range.start,
|
|
end: data.range.end
|
|
});
|
|
if ($scope.should_apply_live_events) {
|
|
// if user has not disabled live event view by scrolling upward, then scroll down to the new content
|
|
current_range = data.range;
|
|
auto_scroll_down = true; // prevent auto load from happening
|
|
$('#pre-container').scrollTop($('#pre-container').prop("scrollHeight"));
|
|
}
|
|
$('#stdoutMoreRowsBottom').fadeOut(400);
|
|
})
|
|
.error(function(data, status) {
|
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
|
msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
|
|
});
|
|
}
|
|
|
|
// lrInfiniteScroll handler
|
|
// grabs the next stdout section
|
|
$scope.stdOutGetNextSection = function(){
|
|
if (current_range.absolute_end > current_range.end){
|
|
var url = $scope.stdoutEndpoint + '?format=json&start_line=' + current_range.end +
|
|
'&end_line=' + (current_range.end + page_size);
|
|
Rest.setUrl(url);
|
|
Rest.get()
|
|
.success(function(data){
|
|
$('#pre-container-content').append(data.content);
|
|
current_range = data.range;
|
|
})
|
|
.error(function(data, status) {
|
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
|
msg: 'Failed to retrieve stdout for job: ' + job_id + '. GET returned: ' + status });
|
|
});
|
|
}
|
|
};
|
|
|
|
// We watch for job status changes here. If the job completes we want to clear out the
|
|
// stdout interval and kill the live_event_processing flag.
|
|
if ($scope.removeJobStatusChange) {
|
|
$scope.removeJobStatusChange();
|
|
}
|
|
$scope.removeJobStatusChange = $rootScope.$on(`ws-${$state.current.name}-jobs`, function(e, data) {
|
|
if (parseInt(data.unified_job_id, 10) === parseInt(job_id,10)) {
|
|
if (data.status === 'failed' || data.status === 'canceled' ||
|
|
data.status === 'error' || data.status === 'successful') {
|
|
if ($rootScope.jobStdOutInterval) {
|
|
window.clearInterval($rootScope.jobStdOutInterval);
|
|
}
|
|
if (live_event_processing) {
|
|
if (loaded_sections.length === 0) {
|
|
loadStdout();
|
|
}
|
|
else {
|
|
getNextSection();
|
|
}
|
|
}
|
|
live_event_processing = false;
|
|
}
|
|
}
|
|
});
|
|
|
|
}];
|