web: refactor the errorsIds into the build action

This change refactors the Console component to avoid processing
build data in the rendering container.

Change-Id: Ice895b3e4f34a0c3c3369269e3e398de7764e7a3
This commit is contained in:
Tristan Cacqueray 2019-08-08 14:26:26 +00:00 committed by James E. Blair
parent 459ee2f1d3
commit e72cb47515
4 changed files with 56 additions and 54 deletions

View File

@ -51,6 +51,19 @@ export const requestBuildOutput = () => ({
type: BUILD_OUTPUT_REQUEST
})
export function didTaskFail(task) {
if (task.failed) {
return true
}
if ('failed_when_result' in task && !task.failed_when_result) {
return false
}
if ('rc' in task && task.rc) {
return true
}
return false
}
const receiveBuildOutput = (buildId, output) => {
const hosts = {}
// Compute stats
@ -88,11 +101,42 @@ const receiveBuildOutput = (buildId, output) => {
}
})
})
// Identify all of the hosttasks (and therefore tasks, plays, and
// playbooks) which have failed. The errorIds are either task or
// play uuids, or the phase+index for the playbook. Since they are
// different formats, we can store them in the same set without
// collisions.
const errorIds = new Set()
output.forEach(playbook => {
playbook.plays.forEach(play => {
play.tasks.forEach(task => {
Object.entries(task.hosts).forEach(([, host]) => {
if (host.results) {
host.results.forEach(result => {
if (didTaskFail(result)) {
errorIds.add(task.task.id)
errorIds.add(play.play.id)
errorIds.add(playbook.phase + playbook.index)
}
})
}
if (didTaskFail(host)) {
errorIds.add(task.task.id)
errorIds.add(play.play.id)
errorIds.add(playbook.phase + playbook.index)
}
})
})
})
})
return {
type: BUILD_OUTPUT_SUCCESS,
buildId: buildId,
hosts: hosts,
output: output,
errorIds: errorIds,
receivedAt: Date.now()
}
}

View File

@ -23,23 +23,12 @@ import {
Modal,
} from 'patternfly-react'
import { didTaskFail } from '../../actions/build'
const INTERESTING_KEYS = ['msg', 'stdout', 'stderr']
function didTaskFail(task) {
if (task.failed) {
return true
}
if ('failed_when_result' in task && !task.failed_when_result) {
return false
}
if ('rc' in task && task.rc) {
return true
}
return false
}
function hostTaskStats (state, host) {
if (didTaskFail(host)) { state.failed += 1}
else if (host.changed) { state.changed += 1}
@ -386,56 +375,20 @@ class PlayBook extends React.Component {
class Console extends React.Component {
static propTypes = {
errorIds: PropTypes.object,
output: PropTypes.array,
displayPath: PropTypes.array,
}
constructor (props) {
super(props)
const { output } = this.props
const errorIds = new Set()
this.errorIds = errorIds
// Identify all of the hosttasks (and therefore tasks, plays, and
// playbooks) which have failed. The errorIds are either task or
// play uuids, or the phase+index for the playbook. Since they are
// different formats, we can store them in the same set without
// collisions.
output.forEach(playbook => {
playbook.plays.forEach(play => {
play.tasks.forEach(task => {
Object.entries(task.hosts).forEach(([, host]) => {
if (host.results) {
host.results.forEach(result => {
if (didTaskFail(result)) {
errorIds.add(task.task.id)
errorIds.add(play.play.id)
errorIds.add(playbook.phase + playbook.index)
}
})
}
if (didTaskFail(host)) {
errorIds.add(task.task.id)
errorIds.add(play.play.id)
errorIds.add(playbook.phase + playbook.index)
}
})
})
})
})
}
render () {
const { output, displayPath } = this.props
const { errorIds, output, displayPath } = this.props
return (
<React.Fragment>
<ListView key="playbooks" className="zuul-console">
{output.map((playbook, idx) => (
<PlayBook key={idx} playbook={playbook} taskPath={[idx.toString()]}
displayPath={displayPath} errorIds={this.errorIds}/>))}
displayPath={displayPath} errorIds={errorIds}/>))}
</ListView>
</React.Fragment>
)

View File

@ -51,7 +51,11 @@ class BuildConsolePage extends Refreshable {
</div>
{build && build.output &&
<Build build={build} active='console'>
<Console output={build.output} displayPath={hash.length>0?hash:undefined}/>
<Console
output={build.output}
errorIds={build.errorIds}
displayPath={hash.length>0?hash:undefined}
/>
</Build>}
</React.Fragment>
)

View File

@ -49,7 +49,8 @@ export default (state = {
return update(state, {$merge: {isFetchingOutput: true}})
case BUILD_OUTPUT_SUCCESS:
state.builds = update(
state.builds, {[action.buildId]: {$merge: {hosts: action.hosts,
state.builds, {[action.buildId]: {$merge: {errorIds: action.errorIds,
hosts: action.hosts,
output: action.output}}})
return update(state, {$merge: {isFetchingOutput: false}})
case BUILD_OUTPUT_FAIL: