From 60d311c1a924f1cd02f2566235919cb4e1eadd4e Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Thu, 5 Apr 2018 16:41:34 -0500 Subject: [PATCH 1/3] don't try to use stats events for adhoc commands --- .../features/output/index.controller.js | 4 +-- .../client/features/output/status.service.js | 36 +++++++++++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/awx/ui/client/features/output/index.controller.js b/awx/ui/client/features/output/index.controller.js index 0fee736561..17dfb63c4c 100644 --- a/awx/ui/client/features/output/index.controller.js +++ b/awx/ui/client/features/output/index.controller.js @@ -95,7 +95,7 @@ function init () { } }); - $scope.$on(resource.ws.events, handleSocketEvent); + $scope.$on(resource.ws.events, handleJobEvent); $scope.$on(resource.ws.status, handleStatusEvent); if (!status.isRunning()) { @@ -107,7 +107,7 @@ function handleStatusEvent (scope, data) { status.pushStatusEvent(data); } -function handleSocketEvent (scope, data) { +function handleJobEvent (scope, data) { engine.pushJobEvent(data); status.pushJobEvent(data); diff --git a/awx/ui/client/features/output/status.service.js b/awx/ui/client/features/output/status.service.js index a3d80dbc01..4d16dc3d07 100644 --- a/awx/ui/client/features/output/status.service.js +++ b/awx/ui/client/features/output/status.service.js @@ -2,7 +2,9 @@ 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'; + const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped']; +const FINISHED = ['running', 'successful', 'failed', 'error']; let moment; @@ -14,6 +16,7 @@ function JobStatusService (_moment_) { this.created = resource.model.get('created'); this.job = resource.model.get('id'); + this.jobType = resource.model.get('type'); this.project = resource.model.get('project'); this.elapsed = resource.model.get('elapsed'); this.started = resource.model.get('started'); @@ -21,6 +24,7 @@ function JobStatusService (_moment_) { this.jobStatus = resource.model.get('status'); this.projectStatus = resource.model.get('summary_fields.project_update.status'); + this.latestTime = null; this.playCount = null; this.taskCount = null; this.hostCount = null; @@ -40,6 +44,15 @@ function JobStatusService (_moment_) { } else if (isProjectEvent) { this.setProjectStatus(data.status); } + + if (this.isCommand()) { + if (_.includes(FINISHED, data.status)) { + if (!this.started && this.latestJobEventTime) { + this.started = moment(this.latestJobEventTime) + .subtract(this.elapsed, 'seconds'); + } + } + } }; this.pushJobEvent = data => { @@ -52,8 +65,8 @@ function JobStatusService (_moment_) { if (isLatest) { this.counter = data.counter; + this.latestTime = data.created; this.elapsed = moment(data.created).diff(this.created, 'seconds'); - this.jobStatus = _.get(data, ['summary_fields', 'job', 'status']); } if (data.event === JOB_START) { @@ -97,14 +110,12 @@ function JobStatusService (_moment_) { }; this.updateStats = () => { - if (!this.statsEvent) { - return; - } - this.updateHostCounts(); - this.setFinished(this.statsEvent.created); - this.setJobStatus(this.statsEvent.failed ? 'failed' : 'successful'); + if (this.statsEvent) { + this.setFinished(this.statsEvent.created); + this.setJobStatus(this.statsEvent.failed ? 'failed' : 'successful'); + } }; this.isRunning = () => (Boolean(this.started) && !this.finished) || @@ -112,6 +123,7 @@ function JobStatusService (_moment_) { (this.jobStatus === 'pending') || (this.jobStatus === 'waiting'); + this.isCommand = () => (this.jobType === 'ad_hoc_command'); this.getPlayCount = () => this.playCount; this.getTaskCount = () => this.taskCount; this.getHostCount = () => this.hostCount; @@ -125,6 +137,16 @@ function JobStatusService (_moment_) { this.setJobStatus = status => { this.jobStatus = status; + + if (this.isCommand() && _.includes(FINISHED, status)) { + if (this.latestTime) { + this.finished = this.latestTime; + + if (!this.started) { + this.started = moment(this.latestTime).subtract(this.elapsed, 'seconds'); + } + } + } }; this.setProjectStatus = status => { From 56935fef94f9a4fefe73715faf03a0f4d4079cbe Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Fri, 6 Apr 2018 14:12:26 -0500 Subject: [PATCH 2/3] account for existence of 'check' project update jobs --- .../features/output/details.directive.js | 51 ++++++++++++------- .../features/output/details.partial.html | 8 +-- awx/ui/client/features/output/jobs.strings.js | 2 +- .../client/features/output/status.service.js | 7 +++ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/awx/ui/client/features/output/details.directive.js b/awx/ui/client/features/output/details.directive.js index 80251e3d9d..e0015d0b94 100644 --- a/awx/ui/client/features/output/details.directive.js +++ b/awx/ui/client/features/output/details.directive.js @@ -184,7 +184,6 @@ function getInventoryDetails () { function getProjectDetails () { const project = resource.model.get('summary_fields.project'); - const projectUpdate = resource.model.get('summary_fields.project_update'); if (!project) { return null; @@ -195,17 +194,32 @@ function getProjectDetails () { const value = $filter('sanitize')(project.name); const tooltip = strings.get('resourceTooltips.PROJECT'); - if (projectUpdate) { - const update = { - link: `/#/jobz/project/${projectUpdate.id}`, - tooltip: strings.get('resourceTooltips.PROJECT_UPDATE'), - status: projectUpdate.status, - }; + return { label, link, value, tooltip }; +} - return { label, link, value, tooltip, update }; +function getProjectStatusDetails (projectStatus) { + const project = resource.model.get('summary_fields.project'); + const jobStatus = projectStatus || resource.model.get('summary_fields.project_update.status'); + + if (!project) { + return null; } - return { label, link, value, tooltip }; + return jobStatus; +} + +function getProjectUpdateDetails (updateId) { + const project = resource.model.get('summary_fields.project'); + const jobId = updateId || resource.model.get('summary_fields.project_update.id'); + + if (!project) { + return null; + } + + const link = `/#/jobz/project/${jobId}`; + const tooltip = strings.get('resourceTooltips.PROJECT_UPDATE'); + + return { link, tooltip }; } function getSCMRevisionDetails () { @@ -495,6 +509,8 @@ function AtJobDetailsController ( vm.sourceWorkflowJob = getSourceWorkflowJobDetails(); vm.inventory = getInventoryDetails(); vm.project = getProjectDetails(); + vm.projectUpdate = getProjectUpdateDetails(); + vm.projectStatus = getProjectStatusDetails(); vm.scmRevision = getSCMRevisionDetails(); vm.playbook = getPlaybookDetails(); vm.resultTraceback = getResultTracebackDetails(); @@ -533,16 +549,15 @@ function AtJobDetailsController ( vm.deleteJob = deleteJob; vm.toggleLabels = toggleLabels; - $scope.$watch(status.getStarted, value => { vm.started = getStartDetails(value); }); - $scope.$watch(status.getJobStatus, value => { vm.status = getStatusDetails(value); }); - $scope.$watch(status.getFinished, value => { vm.finished = getFinishDetails(value); }); + const observe = (getter, transform, key) => { + $scope.$watch(getter, value => { vm[key] = transform(value); }); + }; - $scope.$watch(status.getProjectStatus, value => { - if (!value) return; - - vm.project.update = vm.project.update || {}; - vm.project.update.status = value; - }); + observe(status.getStarted, getStartDetails, 'started'); + observe(status.getJobStatus, getStatusDetails, 'status'); + observe(status.getFinished, getFinishDetails, 'finished'); + observe(status.getProjectUpdateId, getProjectUpdateDetails, 'projectUpdate'); + observe(status.getProjectStatus, getProjectStatusDetails, 'projectStatus'); }; } diff --git a/awx/ui/client/features/output/details.partial.html b/awx/ui/client/features/output/details.partial.html index db5864647f..cc3f18b19d 100644 --- a/awx/ui/client/features/output/details.partial.html +++ b/awx/ui/client/features/output/details.partial.html @@ -119,11 +119,11 @@
- - + this.hostStatusCounts || {}; this.getJobStatus = () => this.jobStatus; this.getProjectStatus = () => this.projectStatus; + this.getProjectUpdateId = () => this.projectUpdateId; this.getElapsed = () => this.elapsed; this.getStatsEvent = () => this.statsEvent; this.getStarted = () => this.started; @@ -153,6 +156,10 @@ function JobStatusService (_moment_) { this.projectStatus = status; }; + this.setProjectUpdateId = id => { + this.projectUpdateId = id; + }; + this.setFinished = time => { this.finished = time; }; From 78e0c02a08615ef150687308f64274f243f81e23 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Mon, 9 Apr 2018 08:36:21 -0400 Subject: [PATCH 3/3] no stats event expected for inventory updates --- .../client/features/output/status.service.js | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/awx/ui/client/features/output/status.service.js b/awx/ui/client/features/output/status.service.js index 6af3bce91d..638d2ff399 100644 --- a/awx/ui/client/features/output/status.service.js +++ b/awx/ui/client/features/output/status.service.js @@ -4,7 +4,7 @@ const PLAY_START = 'playbook_on_play_start'; const TASK_START = 'playbook_on_task_start'; const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped']; -const FINISHED = ['running', 'successful', 'failed', 'error']; +const FINISHED = ['successful', 'failed', 'error']; let moment; @@ -46,15 +46,6 @@ function JobStatusService (_moment_) { this.setProjectStatus(data.status); this.setProjectUpdateId(data.unified_job_id); } - - if (this.isCommand()) { - if (_.includes(FINISHED, data.status)) { - if (!this.started && this.latestJobEventTime) { - this.started = moment(this.latestJobEventTime) - .subtract(this.elapsed, 'seconds'); - } - } - } }; this.pushJobEvent = data => { @@ -72,7 +63,7 @@ function JobStatusService (_moment_) { } if (data.event === JOB_START) { - this.started = data.created; + this.started = this.started || data.created; } if (data.event === PLAY_START) { @@ -125,7 +116,9 @@ function JobStatusService (_moment_) { (this.jobStatus === 'pending') || (this.jobStatus === 'waiting'); - this.isCommand = () => (this.jobType === 'ad_hoc_command'); + this.isExpectingStatsEvent = () => (this.jobType === 'job') || + (this.jobType === 'project_update'); + this.getPlayCount = () => this.playCount; this.getTaskCount = () => this.taskCount; this.getHostCount = () => this.hostCount; @@ -141,11 +134,11 @@ function JobStatusService (_moment_) { this.setJobStatus = status => { this.jobStatus = status; - if (this.isCommand() && _.includes(FINISHED, status)) { + if (!this.isExpectingStatsEvent() && _.includes(FINISHED, status)) { if (this.latestTime) { - this.finished = this.latestTime; + this.setFinished(this.latestTime); - if (!this.started) { + if (!this.started && this.elapsed) { this.started = moment(this.latestTime).subtract(this.elapsed, 'seconds'); } }