// 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 moment from 'moment' import 'moment-duration-format' import * as React from 'react' import PropTypes from 'prop-types' import ReactJson from 'react-json-view' import { Icon, ListView, Row, Col, Modal, } from 'patternfly-react' import { ContainerNodeIcon, InfoCircleIcon, SearchPlusIcon, } from '@patternfly/react-icons' import { hasInterestingKeys, findLoopLabel, shouldIncludeKey, makeTaskPath, taskPathMatches, } from '../../actions/build' const INTERESTING_KEYS = ['msg', 'stdout', 'stderr'] class TaskOutput extends React.Component { static propTypes = { data: PropTypes.object, include: PropTypes.array, } renderResults(value) { const interesting_results = [] value.forEach((result, idx) => { const keys = Object.entries(result).filter( ([key, value]) => shouldIncludeKey( key, value, true, this.props.include)) if (keys.length) { interesting_results.push(idx) } }) return (
{interesting_results.length>0 &&
results
{interesting_results.map((idx) => (

{idx}: {findLoopLabel(value[idx])}

{Object.entries(value[idx]).map(([key, value]) => ( this.renderData(key, value, true) ))}
))}
}
) } renderData(key, value, ignore_underscore) { let ret if (!shouldIncludeKey(key, value, ignore_underscore, this.props.include)) { return () } if (value === null) { ret = (
          null
        
) } else if (typeof(value) === 'string') { ret = (
          {value}
        
) } else if (typeof(value) === 'object') { ret = (
          
        
) } else { ret = (
          {value.toString()}
        
) } return (
{ret &&
{key}
} {ret && ret}
) } render () { const { data } = this.props return ( {Object.entries(data).map(([key, value]) => ( key==='results'?this.renderResults(value):this.renderData(key, value) ))} ) } } class HostTask extends React.Component { static propTypes = { hostname: PropTypes.string, task: PropTypes.object, host: PropTypes.object, errorIds: PropTypes.object, taskPath: PropTypes.array, displayPath: PropTypes.array, } state = { showModal: false, failed: false, changed: false, skipped: false, ok: false } open = () => { this.setState({ showModal: true}) } close = () => { this.setState({ showModal: false}) } constructor (props) { super(props) const { host, taskPath, displayPath } = this.props if (host.failed) { this.state.failed = true } else if (host.changed) { this.state.changed = true } else if (host.skipped) { this.state.skipped = true } else { this.state.ok = true } if (taskPathMatches(taskPath, displayPath)) this.state.showModal = true } render () { const { hostname, task, host, taskPath, errorIds } = this.props const ai = [] if (this.state.failed) { ai.push( FAILED ) } else if (this.state.changed) { ai.push( CHANGED ) } else if (this.state.skipped) { ai.push( SKIPPED ) } else if (this.state.ok) { ai.push( OK ) } ai.push( {hostname} ) let duration = moment.duration( moment(task.task.duration.end).diff(task.task.duration.start) ).format({ template: 'h [hr] m [min] s [sec]', largest: 2, minValue: 1, }) ai.push( {duration} ) const expand = errorIds.has(task.task.id) let name = task.task.name if (!name) { name = host.action } if (task.role) { name = task.role.name + ': ' + name } const has_interesting_keys = hasInterestingKeys(this.props.host, INTERESTING_KEYS) let lc = undefined if (!has_interesting_keys) { lc = [] } return ( {has_interesting_keys &&
                 
               
}
{hostname}
) } } class PlayBook extends React.Component { static propTypes = { playbook: PropTypes.object, errorIds: PropTypes.object, taskPath: PropTypes.array, displayPath: PropTypes.array, } render () { const { playbook, errorIds, taskPath, displayPath } = this.props const expandAll = (playbook.phase === 'run') const expand = (expandAll || errorIds.has(playbook.phase + playbook.index) || taskPathMatches(taskPath, displayPath)) const ai = [] if (playbook.trusted) { ai.push( Trusted ) } return ( {playbook.plays.map((play, idx) => ( Play: {play.play.name} {play.tasks.map((task, idx2) => ( Object.entries(task.hosts).map(([hostname, host]) => ( ))))} ))} ) } } class Console extends React.Component { static propTypes = { errorIds: PropTypes.object, output: PropTypes.array, displayPath: PropTypes.array, } render () { const { errorIds, output, displayPath } = this.props return ( {output.map((playbook, idx) => ( ))} ) } } export default Console