diff options
author | Tristan Cacqueray <tdecacqu@redhat.com> | 2018-12-14 05:59:33 +0000 |
---|---|---|
committer | Tristan Cacqueray <tdecacqu@redhat.com> | 2018-12-14 08:33:48 +0000 |
commit | 2f8a1be7c9a5ad6b6afe4512817be2948d9c41c5 (patch) | |
tree | 7f5b32dacfb8432947338e60f961448b99895bee /web/src/containers/build/BuildOutput.jsx | |
parent | ed1d588785fc336fc5933e26083c843357a929db (diff) | |
download | zuul-2f8a1be7c9a5ad6b6afe4512817be2948d9c41c5.tar.gz |
web: add errors from the job-output to the build page
This change updates the build page to fetch the job-output.json file
and display the failed tasks. Logserver needs to enables CORS
header for the zuul-web service.
Change-Id: Ied9d1bb6489f608bc5402a98c8ae3a24b37b91e2
Diffstat (limited to 'web/src/containers/build/BuildOutput.jsx')
-rw-r--r-- | web/src/containers/build/BuildOutput.jsx | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/web/src/containers/build/BuildOutput.jsx b/web/src/containers/build/BuildOutput.jsx new file mode 100644 index 000000000..a06c3abd8 --- /dev/null +++ b/web/src/containers/build/BuildOutput.jsx @@ -0,0 +1,111 @@ +// Copyright 2018 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +import * as React from 'react' +import PropTypes from 'prop-types' +import { Panel } from 'react-bootstrap' +import { + Icon, + ListView, +} from 'patternfly-react' + + +class BuildOutput extends React.Component { + static propTypes = { + output: PropTypes.object, + } + + renderHosts (hosts) { + return ( + <ListView> + {Object.entries(hosts).map(([host, values]) => ( + <ListView.Item + key={host} + heading={host} + additionalInfo={[ + <ListView.InfoItem key="ok" title="Task OK"> + <Icon type='pf' name='info' /> + <strong>{values.ok}</strong> + </ListView.InfoItem>, + <ListView.InfoItem key="changed" title="Task changed"> + <Icon type='pf' name='ok' /> + <strong>{values.changed}</strong> + </ListView.InfoItem>, + <ListView.InfoItem key="fail" title="Task failure"> + <Icon type='pf' name='error-circle-o' /> + <strong>{values.failures}</strong> + </ListView.InfoItem> + ]} + /> + ))} + </ListView> + ) + } + + renderFailedTask (host, task) { + return ( + <Panel key={host + task.zuul_log_id}> + <Panel.Heading>{host}: {task.name}</Panel.Heading> + <Panel.Body> + {task.invocation && task.invocation.module_args && + task.invocation.module_args._raw_params && ( + <strong key="cmd"> + {task.invocation.module_args._raw_params} <br /> + </strong> + )} + {task.msg && ( + <pre key="msg">{task.msg}</pre> + )} + {task.exception && ( + <pre key="exc">{task.exception}</pre> + )} + {task.stdout_lines && task.stdout_lines.length > 0 && ( + <span key="stdout" style={{whiteSpace: 'pre'}} title="stdout"> + {task.stdout_lines.slice(-42).map((line, idx) => ( + <span key={idx}>{line}<br/></span>))} + <br /> + </span> + )} + {task.stderr_lines && task.stderr_lines.length > 0 && ( + <span key="stderr" style={{whiteSpace: 'pre'}} title="stderr"> + {task.stderr_lines.slice(-42).map((line, idx) => ( + <span key={idx}>{line}<br/></span>))} + <br /> + </span> + )} + </Panel.Body> + </Panel> + ) + } + + render () { + const { output } = this.props + return ( + <React.Fragment> + <div key="tasks"> + {Object.entries(output) + .filter(([, values]) => values.failed.length > 0) + .map(([host, values]) => (values.failed.map(failed => ( + this.renderFailedTask(host, failed)))))} + </div> + <div key="hosts"> + {this.renderHosts(output)} + </div> + </React.Fragment> + ) + } +} + + +export default BuildOutput |