mirror of
https://github.com/ansible/awx.git
synced 2026-03-09 05:29:26 -02:30
add event processing for stats and host status components
This commit is contained in:
@@ -206,12 +206,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.HostStatusBar-ok,
|
.HostStatusBar-ok,
|
||||||
.HostStatusBar-changed,
|
.HostStatusBar-changed,
|
||||||
.HostStatusBar-unreachable,
|
.HostStatusBar-dark,
|
||||||
.HostStatusBar-failed,
|
.HostStatusBar-failed,
|
||||||
.HostStatusBar-skipped,
|
.HostStatusBar-skipped,
|
||||||
.HostStatusBar-noData {
|
.HostStatusBar-noData {
|
||||||
@@ -231,7 +230,7 @@
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.HostStatusBar-unreachable {
|
.HostStatusBar-dark {
|
||||||
background-color: @default-unreachable;
|
background-color: @default-unreachable;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
@@ -265,7 +264,7 @@
|
|||||||
background-color: @default-succ;
|
background-color: @default-succ;
|
||||||
}
|
}
|
||||||
|
|
||||||
.HostStatusBar-tooltipBadge--unreachable {
|
.HostStatusBar-tooltipBadge--dark {
|
||||||
background-color: @default-unreachable;
|
background-color: @default-unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ function AtDetailsController (
|
|||||||
|
|
||||||
vm.init = _$scope_ => {
|
vm.init = _$scope_ => {
|
||||||
$scope = _$scope_;
|
$scope = _$scope_;
|
||||||
resource = $scope.resource;
|
resource = $scope.resource; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
vm.status = getStatusDetails();
|
vm.status = getStatusDetails();
|
||||||
vm.started = getStartTimeDetails();
|
vm.started = getStartTimeDetails();
|
||||||
@@ -466,27 +466,35 @@ function AtDetailsController (
|
|||||||
vm.extraVars = getExtraVarsDetails();
|
vm.extraVars = getExtraVarsDetails();
|
||||||
vm.labels = getLabelDetails();
|
vm.labels = getLabelDetails();
|
||||||
|
|
||||||
|
// Relaunch Component
|
||||||
|
vm.job = _.get(resource.model, 'model.GET', {});
|
||||||
|
|
||||||
|
// XX - Codemirror
|
||||||
|
if (vm.extraVars) {
|
||||||
|
const cm = {
|
||||||
|
parseType: 'yaml',
|
||||||
|
$apply: $scope.$apply,
|
||||||
|
variables: vm.extraVars.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseTypeChange({
|
||||||
|
field_id: 'cm-extra-vars',
|
||||||
|
readOnly: true,
|
||||||
|
scope: cm,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
vm.cancelJob = cancelJob;
|
vm.cancelJob = cancelJob;
|
||||||
vm.deleteJob = deleteJob;
|
vm.deleteJob = deleteJob;
|
||||||
vm.toggleLabels = toggleLabels;
|
vm.toggleLabels = toggleLabels;
|
||||||
|
|
||||||
const observe = (key, transform) => {
|
const observe = (key, transform) => {
|
||||||
$scope.$watch(key, value => { this[key] = transform(value); });
|
$scope.$watch(key, value => { vm[key] = transform(value); });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
observe('finished', getFinishTimeDetails);
|
||||||
observe('status', getStatusDetails);
|
observe('status', getStatusDetails);
|
||||||
observe('started', getStartTimeDetails);
|
observe('started', getStartTimeDetails);
|
||||||
observe('finished', getFinishTimeDetails);
|
|
||||||
|
|
||||||
// relaunch component
|
|
||||||
$scope.job = _.get(resource.model, 'model.GET', {});
|
|
||||||
this.job = $scope.job;
|
|
||||||
|
|
||||||
// codemirror
|
|
||||||
if (this.extraVars) {
|
|
||||||
const cm = { parseType: 'yaml', variables: this.extraVars.value, $apply: $scope.$apply };
|
|
||||||
ParseTypeChange({ scope: cm, field_id: 'cm-extra-vars', readOnly: true });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
|
<!-- todo: styling, css etc. - disposition according to project lib conventions -->
|
||||||
<!-- LEFT PANE HEADER -->
|
|
||||||
<div class="JobResults-panelHeader">
|
<div class="JobResults-panelHeader">
|
||||||
<div class="JobResults-panelHeaderText" translate> DETAILS</div>
|
<div class="JobResults-panelHeaderText" translate> DETAILS</div>
|
||||||
<!-- LEFT PANE HEADER ACTIONS -->
|
<!-- LEFT PANE HEADER ACTIONS -->
|
||||||
<div class="JobResults-panelHeaderButtonActions">
|
<div class="JobResults-panelHeaderButtonActions">
|
||||||
<!-- RELAUNCH ACTION -->
|
<!-- RELAUNCH ACTION -->
|
||||||
<at-relaunch state="vm.job"></at-relaunch>
|
<at-relaunch job="vm.job"></at-relaunch>
|
||||||
|
|
||||||
<!-- CANCEL ACTION -->
|
<!-- CANCEL ACTION -->
|
||||||
<button class="List-actionButton List-actionButton--delete"
|
<button class="List-actionButton List-actionButton--delete"
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
let vm;
|
const JOB_START = 'playbook_on_start';
|
||||||
|
const JOB_END = 'playbook_on_stats';
|
||||||
|
const PLAY_START = 'playbook_on_play_start';
|
||||||
|
const TASK_START = 'playbook_on_task_start';
|
||||||
|
|
||||||
let $compile;
|
let $compile;
|
||||||
let $scope;
|
|
||||||
let $q;
|
let $q;
|
||||||
|
let $scope;
|
||||||
|
let $state;
|
||||||
|
let moment;
|
||||||
let page;
|
let page;
|
||||||
|
let qs;
|
||||||
let render;
|
let render;
|
||||||
|
let resource;
|
||||||
let scroll;
|
let scroll;
|
||||||
let stream;
|
let stream;
|
||||||
let resource;
|
|
||||||
let $state;
|
|
||||||
let qs;
|
|
||||||
|
|
||||||
let hack;
|
let vm;
|
||||||
|
|
||||||
|
let eventCounter;
|
||||||
|
let statsEvent;
|
||||||
|
|
||||||
function JobsIndexController (
|
function JobsIndexController (
|
||||||
_resource_,
|
_resource_,
|
||||||
@@ -23,6 +31,7 @@ function JobsIndexController (
|
|||||||
_$q_,
|
_$q_,
|
||||||
_$state_,
|
_$state_,
|
||||||
_qs_,
|
_qs_,
|
||||||
|
_moment_,
|
||||||
) {
|
) {
|
||||||
vm = this || {};
|
vm = this || {};
|
||||||
|
|
||||||
@@ -36,6 +45,8 @@ function JobsIndexController (
|
|||||||
render = _render_;
|
render = _render_;
|
||||||
stream = _stream_;
|
stream = _stream_;
|
||||||
|
|
||||||
|
moment = _moment_;
|
||||||
|
|
||||||
// Development helper(s)
|
// Development helper(s)
|
||||||
vm.clear = devClear;
|
vm.clear = devClear;
|
||||||
|
|
||||||
@@ -69,11 +80,19 @@ function JobsIndexController (
|
|||||||
vm.removeSearchTag = removeSearchTag;
|
vm.removeSearchTag = removeSearchTag;
|
||||||
vm.searchTags = getSearchTags(getCurrentQueryset());
|
vm.searchTags = getSearchTags(getCurrentQueryset());
|
||||||
|
|
||||||
// Host Status Bar
|
// Events
|
||||||
|
eventCounter = null;
|
||||||
|
statsEvent = resource.stats;
|
||||||
|
|
||||||
|
// Status Bar
|
||||||
vm.status = {
|
vm.status = {
|
||||||
|
stats: statsEvent,
|
||||||
|
elapsed: resource.model.get('elapsed'),
|
||||||
running: Boolean(resource.model.get('started')) && !resource.model.get('finished'),
|
running: Boolean(resource.model.get('started')) && !resource.model.get('finished'),
|
||||||
stats: resource.stats,
|
title: resource.model.get('name'),
|
||||||
}
|
plays: null,
|
||||||
|
tasks: null,
|
||||||
|
};
|
||||||
|
|
||||||
// Details
|
// Details
|
||||||
vm.details = {
|
vm.details = {
|
||||||
@@ -83,33 +102,10 @@ function JobsIndexController (
|
|||||||
status: resource.model.get('status'),
|
status: resource.model.get('status'),
|
||||||
};
|
};
|
||||||
|
|
||||||
render.requestAnimationFrame(() => init());
|
render.requestAnimationFrame(() => init(!vm.status.running));
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStreamStart (data) {
|
|
||||||
const status = _.get(data, 'summary_fields.job.status');
|
|
||||||
|
|
||||||
if (!hack) {
|
|
||||||
hack = true;
|
|
||||||
vm.details.status = status;
|
|
||||||
vm.details.started = data.created;
|
|
||||||
|
|
||||||
vm.status.running = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onStreamFinish (data) {
|
|
||||||
const failed = _.get(data, 'summary_fields.job.failed');
|
|
||||||
|
|
||||||
vm.details.status = failed ? 'failed' : 'successful';
|
|
||||||
vm.details.finished = data.created;
|
|
||||||
|
|
||||||
vm.status = { stats: data, running: false };
|
|
||||||
};
|
|
||||||
|
|
||||||
function init (pageMode) {
|
function init (pageMode) {
|
||||||
hack = false;
|
|
||||||
|
|
||||||
page.init({
|
page.init({
|
||||||
resource,
|
resource,
|
||||||
});
|
});
|
||||||
@@ -123,26 +119,68 @@ function init (pageMode) {
|
|||||||
scroll.init({
|
scroll.init({
|
||||||
isAtRest: scrollIsAtRest,
|
isAtRest: scrollIsAtRest,
|
||||||
previous,
|
previous,
|
||||||
next
|
next,
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.init({
|
stream.init({
|
||||||
page,
|
page,
|
||||||
scroll,
|
scroll,
|
||||||
resource,
|
resource,
|
||||||
onStreamStart,
|
onEventFrame (events) {
|
||||||
onStreamFinish,
|
return shift().then(() => append(events, true));
|
||||||
render: events => shift().then(() => append(events, true)),
|
|
||||||
listen: (namespace, listener) => {
|
|
||||||
$scope.$on(namespace, (scope, data) => listener(data));
|
|
||||||
},
|
},
|
||||||
|
onStart () {
|
||||||
|
vm.status.plays = 0;
|
||||||
|
vm.status.tasks = 0;
|
||||||
|
vm.status.running = true;
|
||||||
|
},
|
||||||
|
onStop () {
|
||||||
|
vm.status.stats = statsEvent;
|
||||||
|
vm.status.running = false;
|
||||||
|
|
||||||
|
vm.details.status = statsEvent.failed ? 'failed' : 'successful';
|
||||||
|
vm.details.finished = statsEvent.created;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.$on(resource.ws.namespace, handleSocketEvent);
|
||||||
|
|
||||||
if (pageMode) {
|
if (pageMode) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSocketEvent (scope, data) {
|
||||||
|
const isLatest = ((!eventCounter) || (data.counter > eventCounter));
|
||||||
|
|
||||||
|
if (isLatest) {
|
||||||
|
eventCounter = data.counter;
|
||||||
|
|
||||||
|
vm.details.status = _.get(data, 'summary_fields.job.status');
|
||||||
|
|
||||||
|
vm.status.elapsed = moment(data.created)
|
||||||
|
.diff(resource.model.get('created'), 'seconds');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.event === JOB_START) {
|
||||||
|
vm.details.started = data.created;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.event === PLAY_START) {
|
||||||
|
vm.status.plays++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.event === TASK_START) {
|
||||||
|
vm.status.tasks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.event === JOB_END) {
|
||||||
|
statsEvent = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.pushEventData(data);
|
||||||
|
}
|
||||||
|
|
||||||
function devClear (pageMode) {
|
function devClear (pageMode) {
|
||||||
init(pageMode);
|
init(pageMode);
|
||||||
render.clear();
|
render.clear();
|
||||||
@@ -158,9 +196,11 @@ function next () {
|
|||||||
return shift()
|
return shift()
|
||||||
.then(() => append(events))
|
.then(() => append(events))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if(scroll.isMissing()) {
|
if (scroll.isMissing()) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -242,9 +282,11 @@ function scrollHome () {
|
|||||||
scroll.resume();
|
scroll.resume();
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if(scroll.isMissing()) {
|
if (scroll.isMissing()) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -359,7 +401,7 @@ function toggleSearchKey () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentQueryset () {
|
function getCurrentQueryset () {
|
||||||
const { job_event_search } = $state.params;
|
const { job_event_search } = $state.params; // eslint-disable-line camelcase
|
||||||
|
|
||||||
return qs.decodeArr(job_event_search);
|
return qs.decodeArr(job_event_search);
|
||||||
}
|
}
|
||||||
@@ -414,6 +456,7 @@ JobsIndexController.$inject = [
|
|||||||
'$q',
|
'$q',
|
||||||
'$state',
|
'$state',
|
||||||
'QuerySet',
|
'QuerySet',
|
||||||
|
'moment',
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = JobsIndexController;
|
module.exports = JobsIndexController;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import StreamService from '~features/output/stream.service';
|
|||||||
|
|
||||||
import DetailsDirective from '~features/output/details.directive';
|
import DetailsDirective from '~features/output/details.directive';
|
||||||
import SearchKeyDirective from '~features/output/search-key.directive';
|
import SearchKeyDirective from '~features/output/search-key.directive';
|
||||||
import StatusDirective from '~features/output/status.directive';
|
import StatsDirective from '~features/output/stats.directive';
|
||||||
|
|
||||||
const Template = require('~features/output/index.view.html');
|
const Template = require('~features/output/index.view.html');
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ function resolveResource (
|
|||||||
qs,
|
qs,
|
||||||
Wait
|
Wait
|
||||||
) {
|
) {
|
||||||
const { id, type, job_event_search } = $stateParams;
|
const { id, type, job_event_search } = $stateParams; // eslint-disable-line camelcase
|
||||||
|
|
||||||
let Resource;
|
let Resource;
|
||||||
let related = 'events';
|
let related = 'events';
|
||||||
@@ -61,7 +61,7 @@ function resolveResource (
|
|||||||
const params = { page_size: PAGE_SIZE, order_by: 'start_line' };
|
const params = { page_size: PAGE_SIZE, order_by: 'start_line' };
|
||||||
const config = { pageCache: PAGE_CACHE, pageLimit: PAGE_LIMIT, params };
|
const config = { pageCache: PAGE_CACHE, pageLimit: PAGE_LIMIT, params };
|
||||||
|
|
||||||
if (job_event_search) {
|
if (job_event_search) { // eslint-disable-line camelcase
|
||||||
const queryParams = qs.encodeQuerysetObject(qs.decodeArr(job_event_search));
|
const queryParams = qs.encodeQuerysetObject(qs.decodeArr(job_event_search));
|
||||||
|
|
||||||
Object.assign(config.params, queryParams);
|
Object.assign(config.params, queryParams);
|
||||||
@@ -211,7 +211,7 @@ angular
|
|||||||
.service('JobStreamService', StreamService)
|
.service('JobStreamService', StreamService)
|
||||||
.directive('atDetails', DetailsDirective)
|
.directive('atDetails', DetailsDirective)
|
||||||
.directive('atSearchKey', SearchKeyDirective)
|
.directive('atSearchKey', SearchKeyDirective)
|
||||||
.directive('atStatus', StatusDirective)
|
.directive('atStats', StatsDirective)
|
||||||
.run(JobsRun);
|
.run(JobsRun);
|
||||||
|
|
||||||
export default MODULE_NAME;
|
export default MODULE_NAME;
|
||||||
|
|||||||
@@ -13,7 +13,14 @@
|
|||||||
|
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<at-panel class="at-Stdout">
|
<at-panel class="at-Stdout">
|
||||||
<at-status running="vm.status.running" stats="vm.status.stats"></at-status>
|
<at-stats
|
||||||
|
elapsed="vm.status.elapsed"
|
||||||
|
running="vm.status.running"
|
||||||
|
stats="vm.status.stats"
|
||||||
|
title="vm.status.title"
|
||||||
|
plays="vm.status.plays"
|
||||||
|
tasks="vm.status.tasks">
|
||||||
|
</at-stats>
|
||||||
<!-- search ===================================================================================== -->
|
<!-- search ===================================================================================== -->
|
||||||
<form ng-submit="vm.search()">
|
<form ng-submit="vm.search()">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
|||||||
@@ -250,7 +250,6 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
|
|
||||||
this.clear = () => {
|
this.clear = () => {
|
||||||
const elements = this.el.children();
|
const elements = this.el.children();
|
||||||
|
|
||||||
return this.remove(elements);
|
return this.remove(elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const templateUrl = require('~features/output/status.partial.html');
|
const templateUrl = require('~features/output/stats.partial.html');
|
||||||
|
|
||||||
const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped'];
|
const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped'];
|
||||||
|
|
||||||
@@ -21,23 +21,25 @@ function getHostStatusCounts (statsEvent) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
counts.hosts = countedHostNames.length;
|
||||||
|
|
||||||
return counts;
|
return counts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createStatusBarTooltip (key, count) {
|
function createStatsBarTooltip (key, count) {
|
||||||
const label = `<span class='HostStatusBar-tooltipLabel'>${key}</span>`;
|
const label = `<span class='HostStatusBar-tooltipLabel'>${key}</span>`;
|
||||||
const badge = `<span class='badge HostStatusBar-tooltipBadge HostStatusBar-tooltipBadge--${key}'>${count}</span>`;
|
const badge = `<span class='badge HostStatusBar-tooltipBadge HostStatusBar-tooltipBadge--${key}'>${count}</span>`;
|
||||||
|
|
||||||
return `${label}${badge}`;
|
return `${label}${badge}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function atStatusLink (scope, el, attrs, controllers) {
|
function atStatsLink (scope, el, attrs, controllers) {
|
||||||
const [atStatusController] = controllers;
|
const [atStatsController] = controllers;
|
||||||
|
|
||||||
atStatusController.init(scope);
|
atStatsController.init(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtStatusController (strings) {
|
function AtStatsController (strings) {
|
||||||
const vm = this || {};
|
const vm = this || {};
|
||||||
|
|
||||||
vm.tooltips = {
|
vm.tooltips = {
|
||||||
@@ -46,12 +48,22 @@ function AtStatusController (strings) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vm.init = scope => {
|
vm.init = scope => {
|
||||||
const { running, stats } = scope;
|
const { elapsed, running, stats, title, plays, tasks } = scope;
|
||||||
|
|
||||||
|
vm.title = title;
|
||||||
|
|
||||||
|
vm.plays = plays;
|
||||||
|
vm.tasks = tasks;
|
||||||
|
vm.elapsed = elapsed;
|
||||||
vm.running = running || false;
|
vm.running = running || false;
|
||||||
|
|
||||||
vm.setStats(stats);
|
vm.setStats(stats);
|
||||||
|
|
||||||
|
scope.$watch('elapsed', value => { vm.elapsed = value; });
|
||||||
scope.$watch('running', value => { vm.running = value; });
|
scope.$watch('running', value => { vm.running = value; });
|
||||||
|
scope.$watch('plays', value => { vm.plays = value; });
|
||||||
|
scope.$watch('tasks', value => { vm.tasks = value; });
|
||||||
|
|
||||||
scope.$watch('stats', vm.setStats);
|
scope.$watch('stats', vm.setStats);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,29 +76,34 @@ function AtStatusController (strings) {
|
|||||||
|
|
||||||
statusBarElement.css('flex', `${count} 0 auto`);
|
statusBarElement.css('flex', `${count} 0 auto`);
|
||||||
|
|
||||||
vm.tooltips[key] = createStatusBarTooltip(key, count);
|
vm.tooltips[key] = createStatsBarTooltip(key, count);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
vm.hosts = counts.hosts;
|
||||||
vm.statsAreAvailable = Boolean(stats);
|
vm.statsAreAvailable = Boolean(stats);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function atStatus () {
|
function atStats () {
|
||||||
return {
|
return {
|
||||||
templateUrl,
|
templateUrl,
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
require: ['atStatus'],
|
require: ['atStats'],
|
||||||
controllerAs: 'vm',
|
controllerAs: 'vm',
|
||||||
link: atStatusLink,
|
link: atStatsLink,
|
||||||
controller: [
|
controller: [
|
||||||
'JobStrings',
|
'JobStrings',
|
||||||
AtStatusController
|
AtStatsController
|
||||||
],
|
],
|
||||||
scope: {
|
scope: {
|
||||||
|
elapsed: '=',
|
||||||
running: '=',
|
running: '=',
|
||||||
stats: '=',
|
stats: '=',
|
||||||
|
title: '=',
|
||||||
|
plays: '=',
|
||||||
|
tasks: '=',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default atStatus;
|
export default atStats;
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
const JOB_START = 'playbook_on_start';
|
|
||||||
const JOB_END = 'playbook_on_stats';
|
const JOB_END = 'playbook_on_stats';
|
||||||
const MAX_LAG = 120;
|
const MAX_LAG = 120;
|
||||||
|
|
||||||
function JobStreamService ($q) {
|
function JobStreamService ($q) {
|
||||||
this.init = ({ resource, scroll, page, onStreamStart, onStreamFinish, render, listen }) => {
|
this.init = ({ resource, scroll, page, onEventFrame, onStart, onStop }) => {
|
||||||
this.resource = resource;
|
this.resource = resource;
|
||||||
this.scroll = scroll;
|
this.scroll = scroll;
|
||||||
this.page = page;
|
this.page = page;
|
||||||
@@ -13,20 +12,21 @@ function JobStreamService ($q) {
|
|||||||
this.pageCount = 0;
|
this.pageCount = 0;
|
||||||
this.chain = $q.resolve();
|
this.chain = $q.resolve();
|
||||||
this.factors = this.getBatchFactors(this.resource.page.size);
|
this.factors = this.getBatchFactors(this.resource.page.size);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
started: false,
|
started: false,
|
||||||
paused: false,
|
paused: false,
|
||||||
pausing: false,
|
pausing: false,
|
||||||
resuming: false,
|
resuming: false,
|
||||||
ending: false,
|
ending: false,
|
||||||
ended: false
|
ended: false,
|
||||||
|
counting: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hooks = {
|
this.hooks = {
|
||||||
onStreamStart,
|
onEventFrame,
|
||||||
onStreamFinish,
|
onStart,
|
||||||
render,
|
onStop,
|
||||||
listen,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.lines = {
|
this.lines = {
|
||||||
@@ -36,8 +36,6 @@ function JobStreamService ($q) {
|
|||||||
min: 0,
|
min: 0,
|
||||||
max: 0
|
max: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hooks.listen(resource.ws.namespace, this.listener);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getBatchFactors = size => {
|
this.getBatchFactors = size => {
|
||||||
@@ -91,7 +89,7 @@ function JobStreamService ($q) {
|
|||||||
this.lines.used.push(i);
|
this.lines.used.push(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
let missing = [];
|
const missing = [];
|
||||||
for (let i = this.lines.min; i < this.lines.max; i++) {
|
for (let i = this.lines.min; i < this.lines.max; i++) {
|
||||||
if (this.lines.used.indexOf(i) === -1) {
|
if (this.lines.used.indexOf(i) === -1) {
|
||||||
missing.push(i);
|
missing.push(i);
|
||||||
@@ -107,25 +105,19 @@ function JobStreamService ($q) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.listener = data => {
|
this.pushEventData = data => {
|
||||||
this.lag++;
|
this.lag++;
|
||||||
|
|
||||||
this.chain = this.chain
|
this.chain = this.chain
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// console.log(data);
|
|
||||||
if (!this.isActive()) {
|
if (!this.isActive()) {
|
||||||
this.start();
|
this.start();
|
||||||
if (!this.isEnding()) {
|
|
||||||
this.hooks.onStreamStart(data);
|
|
||||||
}
|
|
||||||
} else if (data.event === JOB_END) {
|
} else if (data.event === JOB_END) {
|
||||||
if (this.isPaused()) {
|
if (this.isPaused()) {
|
||||||
this.end(true);
|
this.end(true);
|
||||||
} else {
|
} else {
|
||||||
this.end();
|
this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hooks.onStreamFinish(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkLines(data);
|
this.checkLines(data);
|
||||||
@@ -142,9 +134,11 @@ function JobStreamService ($q) {
|
|||||||
return this.renderFrame(events);
|
return this.renderFrame(events);
|
||||||
})
|
})
|
||||||
.then(() => --this.lag);
|
.then(() => --this.lag);
|
||||||
|
|
||||||
|
return this.chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.renderFrame = events => this.hooks.render(events)
|
this.renderFrame = events => this.hooks.onEventFrame(events)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (this.scroll.isLocked()) {
|
if (this.scroll.isLocked()) {
|
||||||
this.scroll.scrollToBottom();
|
this.scroll.scrollToBottom();
|
||||||
@@ -190,9 +184,13 @@ function JobStreamService ($q) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.start = () => {
|
this.start = () => {
|
||||||
this.state.started = true;
|
if (!this.state.ending && !this.state.ended) {
|
||||||
this.scroll.pause();
|
this.state.started = true;
|
||||||
this.scroll.lock();
|
this.scroll.pause();
|
||||||
|
this.scroll.lock();
|
||||||
|
|
||||||
|
this.hooks.onStart();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.end = done => {
|
this.end = done => {
|
||||||
@@ -202,13 +200,15 @@ function JobStreamService ($q) {
|
|||||||
this.scroll.unlock();
|
this.scroll.unlock();
|
||||||
this.scroll.resume();
|
this.scroll.resume();
|
||||||
|
|
||||||
|
this.hooks.onStop();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state.ending = true;
|
this.state.ending = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isReadyToRender = () => this.isEnding() ||
|
this.isReadyToRender = () => this.isDone() ||
|
||||||
(!this.isPaused() && this.hasAllLines() && this.isBatchFull());
|
(!this.isPaused() && this.hasAllLines() && this.isBatchFull());
|
||||||
this.hasAllLines = () => this.lines.ready;
|
this.hasAllLines = () => this.lines.ready;
|
||||||
this.isBatchFull = () => this.count % this.framesPerRender === 0;
|
this.isBatchFull = () => this.count % this.framesPerRender === 0;
|
||||||
|
|||||||
@@ -44,3 +44,15 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.at-Panel-label {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: @default-interface-txt;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal!important;
|
||||||
|
width: 30%;
|
||||||
|
|
||||||
|
@media screen and (max-width: @breakpoint-md) {
|
||||||
|
flex: 2.5 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ function atRelaunchCtrl (
|
|||||||
jobObj.postRelaunch(launchParams)
|
jobObj.postRelaunch(launchParams)
|
||||||
.then((launchRes) => {
|
.then((launchRes) => {
|
||||||
if (!$state.includes('jobs')) {
|
if (!$state.includes('jobs')) {
|
||||||
$state.go('jobResult', { id: launchRes.data.id }, { reload: true });
|
const relaunchType = launchRes.data.type === 'job' ? 'playbook' : launchRes.data.type;
|
||||||
|
$state.go('jobz', { id: launchRes.data.id, type: relaunchType }, { reload: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,7 +354,6 @@ function has (method, keys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function extend (related, config = {}) {
|
function extend (related, config = {}) {
|
||||||
|
|
||||||
const req = this.parseRequestConfig('GET', config);
|
const req = this.parseRequestConfig('GET', config);
|
||||||
|
|
||||||
if (_.get(config, 'params.page_size')) {
|
if (_.get(config, 'params.page_size')) {
|
||||||
@@ -614,7 +613,11 @@ function create (method, resource, config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setEndpoint (resource) {
|
function setEndpoint (resource) {
|
||||||
this.endpoint = `${this.path}${resource}/`;
|
if (Array.isArray(resource)) {
|
||||||
|
this.endpoint = `${this.path}${resource[0]}/`;
|
||||||
|
} else {
|
||||||
|
this.endpoint = `${this.path}${resource}/`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseRequestConfig (method, resource, config) {
|
function parseRequestConfig (method, resource, config) {
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ function getStats () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function JobModel (method, resource, config) {
|
function JobModel (method, resource, config) {
|
||||||
BaseModel.call(this, 'jobs');
|
BaseModel.call(this, 'jobs');
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ function getStats () {
|
|||||||
return Promise.reject(new Error('No related property, events, exists'));
|
return Promise.reject(new Error('No related property, events, exists'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const req = {
|
const req = {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `${this.path}${this.get('id')}/events/`,
|
url: `${this.path}${this.get('id')}/events/`,
|
||||||
@@ -20,19 +18,18 @@ function getStats () {
|
|||||||
|
|
||||||
return $http(req)
|
return $http(req)
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
console.log(data);
|
|
||||||
if (data.results.length > 0) {
|
if (data.results.length > 0) {
|
||||||
return data.results[0];
|
return data.results[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ProjectUpdateModel (method, resource, config) {
|
function ProjectUpdateModel (method, resource, config) {
|
||||||
BaseModel.call(this, 'project_updates');
|
BaseModel.call(this, 'project_updates');
|
||||||
|
|
||||||
this.getStats = getStats;
|
this.getStats = getStats.bind(this);
|
||||||
|
|
||||||
this.Constructor = ProjectUpdateModel;
|
this.Constructor = ProjectUpdateModel;
|
||||||
|
|
||||||
@@ -40,7 +37,7 @@ function ProjectUpdateModel (method, resource, config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ProjectUpdateModelLoader (_$http_, _BaseModel_) {
|
function ProjectUpdateModelLoader (_$http_, _BaseModel_) {
|
||||||
$http = _$http_;
|
$http = _$http_;
|
||||||
BaseModel = _BaseModel_;
|
BaseModel = _BaseModel_;
|
||||||
|
|
||||||
return ProjectUpdateModel;
|
return ProjectUpdateModel;
|
||||||
|
|||||||
@@ -50,6 +50,17 @@
|
|||||||
font-size: @at-font-size-body;
|
font-size: @at-font-size-body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.at-ButtonIcon-noborder {
|
||||||
|
padding: 4px @at-padding-button-horizontal;
|
||||||
|
font-size: @at-font-size-body;
|
||||||
|
.at-mixin-Button();
|
||||||
|
.at-mixin-ButtonHollow(
|
||||||
|
'at-color-default',
|
||||||
|
'at-color-default',
|
||||||
|
'at-color-button-text-default'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
.at-Button--expand {
|
.at-Button--expand {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,3 +20,11 @@
|
|||||||
.at-u-clear {
|
.at-u-clear {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.at-u-noBorder {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-u-floatRight {
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.HostStatusBar-ok,
|
.HostStatusBar-ok,
|
||||||
@@ -32,6 +31,11 @@
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.HostStatusBar-dark {
|
||||||
|
background-color: @default-unreachable;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.HostStatusBar-failures {
|
.HostStatusBar-failures {
|
||||||
background-color: @default-err;
|
background-color: @default-err;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
@@ -65,6 +69,10 @@
|
|||||||
background-color: @default-unreachable;
|
background-color: @default-unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.HostStatusBar-tooltipBadge--dark {
|
||||||
|
background-color: @default-unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
.HostStatusBar-tooltipBadge--skipped {
|
.HostStatusBar-tooltipBadge--skipped {
|
||||||
background-color: @default-link;
|
background-color: @default-link;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,9 +126,8 @@ standard-out-log {
|
|||||||
|
|
||||||
.StandardOut-panelHeaderActions {
|
.StandardOut-panelHeaderActions {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
display: flex;
|
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
font-size: 20px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.StandardOut-actions {
|
.StandardOut-actions {
|
||||||
@@ -137,12 +136,11 @@ standard-out-log {
|
|||||||
|
|
||||||
.StandardOut-actionButton {
|
.StandardOut-actionButton {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
height: 30px;
|
height: 20px;
|
||||||
min-width: 30px;
|
min-width: 30px;
|
||||||
color: @list-action-icon;
|
color: @list-action-icon;
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 50%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.StandardOut-actionButton:hover {
|
.StandardOut-actionButton:hover {
|
||||||
|
|||||||
Reference in New Issue
Block a user