Skip to content

Commit

Permalink
Merge pull request #1503 from HubSpot/dont-link-nonexistent-logs
Browse files Browse the repository at this point in the history
Don't show logs panel if task never running
  • Loading branch information
ssalinas authored Apr 28, 2017
2 parents 49f99c9 + 92f1de4 commit 389be84
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 28 deletions.
29 changes: 20 additions & 9 deletions SingularityUI/app/components/taskDetail/TaskDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import TaskLbUpdates from './TaskLbUpdates';
import TaskInfo from './TaskInfo';
import TaskEnvVars from './TaskEnvVars';
import TaskHealthchecks from './TaskHealthchecks';
import TaskState from './TaskState';
import TaskStatus from './TaskStatus';

class TaskDetail extends Component {

Expand Down Expand Up @@ -76,6 +78,7 @@ class TaskDetail extends Component {
healthcheckResults: PropTypes.array,
ports: PropTypes.array,
directory: PropTypes.string,
status: PropTypes.oneOf([TaskStatus.RUNNING, TaskStatus.STOPPED, TaskStatus.NEVER_RAN]),
isStillRunning: PropTypes.bool,
isCleaning: PropTypes.bool,
loadBalancerUpdates: PropTypes.array
Expand Down Expand Up @@ -219,14 +222,12 @@ class TaskDetail extends Component {
cleanupType = cleanup.cleanupType;
}

const taskState = this.props.task.taskUpdates && (
<div className="col-xs-6 task-state-header">
<h1>
<span className={`label label-${Utils.getLabelClassFromTaskState(_.last(this.props.task.taskUpdates).taskState)} task-state-header-label`}>
{Utils.humanizeText(_.last(this.props.task.taskUpdates).taskState)} {cleanupType && `(${Utils.humanizeText(cleanupType)})`}
</span>
</h1>
</div>
const taskState = (
<TaskState
status={this.props.task.status}
updates={this.props.task.taskUpdates}
cleanupType={cleanupType}
/>
);

let destroy = false;
Expand Down Expand Up @@ -415,14 +416,16 @@ class TaskDetail extends Component {
return cleanupToTest.taskId.id === this.props.taskId;
});
const filesToDisplay = this.props.files[`${this.props.params.taskId}/${this.props.currentFilePath}`] && this.analyzeFiles(this.props.files[`${this.props.taskId}/${this.props.currentFilePath}`].data);
const topLevelFiles = this.props.files[`${this.props.params.taskId}/`] && this.analyzeFiles(this.props.files[`${this.props.taskId}/`].data);
const filesAvailable = topLevelFiles && !_.isEmpty(topLevelFiles.files);

return (
<div className="task-detail detail-view">
{this.renderHeader(cleanup)}
<TaskAlerts task={this.props.task} deploy={this.props.deploy} pendingDeploys={this.props.pendingDeploys} />
<TaskMetadataAlerts task={this.props.task} />
<TaskHistory taskUpdates={this.props.task.taskUpdates} />
<TaskLatestLog taskId={this.props.taskId} isStillRunning={this.props.task.isStillRunning} />
<TaskLatestLog taskId={this.props.taskId} status={this.props.task.status} available={filesAvailable} />
{this.renderFiles(filesToDisplay)}
{_.isEmpty(this.props.s3Logs) || <TaskS3Logs taskId={this.props.task.task.taskId.id} s3Files={this.props.s3Logs} taskStartedAt={this.props.task.task.taskId.startedAt} />}
{_.isEmpty(this.props.task.loadBalancerUpdates) || <TaskLbUpdates loadBalancerUpdates={this.props.task.loadBalancerUpdates} />}
Expand Down Expand Up @@ -452,10 +455,18 @@ function mapHealthchecksToProps(task) {
function mapTaskToProps(task) {
task.lastKnownState = _.last(task.taskUpdates);
let isStillRunning = true;
let status = TaskStatus.RUNNING;

if (task.taskUpdates && _.contains(Utils.TERMINAL_TASK_STATES, task.lastKnownState.taskState)) {
if (_.contains(_.map(task.taskUpdates, (update) => update.taskState), 'TASK_RUNNING')) {
status = TaskStatus.STOPPED;
} else {
status = TaskStatus.NEVER_RAN;
}
isStillRunning = false;
}
task.isStillRunning = isStillRunning;
task.status = status;

task.isCleaning = task.lastKnownState && task.lastKnownState.taskState === 'TASK_CLEANING';

Expand Down
55 changes: 36 additions & 19 deletions SingularityUI/app/components/taskDetail/TaskLatestLog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,48 @@ import { Glyphicon } from 'react-bootstrap';
import { Link } from 'react-router';

import Section from '../common/Section';
import TaskStatus from './TaskStatus';

function TaskLatestLog (props) {
const link = props.isStillRunning ? (
<Link to={Utils.tailerPath(props.taskId, config.runningTaskLogPath)} title="Log">
<span><Glyphicon glyph="file" /> {Utils.fileName(config.runningTaskLogPath)}</span>
</Link>
) : (
<Link to={Utils.tailerPath(props.taskId, config.finishedTaskLogPath)} title="Log">
<span><Glyphicon glyph="file" /> {Utils.fileName(config.finishedTaskLogPath)}</span>
</Link>
);
return (
<Section title="Logs" id="logs">
<div className="row">
<div className="col-md-4">
<h4>{link}</h4>
const getLink = (status, taskId) => {
if (status === TaskStatus.RUNNING) {
return (
<Link to={Utils.tailerPath(taskId, config.runningTaskLogPath)} title="Log">
<span><Glyphicon glyph="file" /> {Utils.fileName(config.runningTaskLogPath)}</span>
</Link>
);
} else if (status === TaskStatus.STOPPED) {
return (
<Link to={Utils.tailerPath(taskId, config.finishedTaskLogPath)} title="Log">
<span><Glyphicon glyph="file" /> {Utils.fileName(config.finishedTaskLogPath)}</span>
</Link>
);
}

return null;
};

function TaskLatestLog({status, taskId, available}) {
const link = getLink(status, taskId);

if (status === TaskStatus.NEVER_RAN || !available) {
return null;
} else {
return (
<Section title="Logs" id="logs">
<div className="row">
<div className="col-md-4">
<h4>{link}</h4>
</div>
</div>
</div>
</Section>
);
</Section>
);
}
}

TaskLatestLog.propTypes = {
taskId: PropTypes.string.isRequired,
isStillRunning: PropTypes.bool
status: PropTypes.oneOf([TaskStatus.RUNNING, TaskStatus.STOPPED, TaskStatus.NEVER_RAN]),
available: PropTypes.bool,
};

export default TaskLatestLog;
48 changes: 48 additions & 0 deletions SingularityUI/app/components/taskDetail/TaskState.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { PropTypes } from 'react';
import Utils from '../../utils';
import TaskStatus from './TaskStatus';

const labelText = (status, currentState, cleanupType) => {
if (status === TaskStatus.NEVER_RAN) {
return 'Task aborted';
} else if (cleanupType) {
return `${Utils.humanizeText(currentState)} (${Utils.humanizeText(cleanupType)})`;
}

return Utils.humanizeText(currentState);
};

const labelClass = (status, currentState) => {
if (status === TaskStatus.NEVER_RAN) {
return 'info';
}

return Utils.getLabelClassFromTaskState(currentState);
};

const TaskState = ({status, updates, cleanupType}) => {
if (updates) {
const currentState = _.last(updates).taskState;
return (
<div className="col-xs-6 task-state-header">
<h1>
<span className={`label label-${labelClass(status, currentState)} task-state-header-label`}>
{labelText(status, currentState, cleanupType)}
</span>
</h1>
</div>
);
}

return null;
};

TaskState.propTypes = {
status: PropTypes.oneOf([TaskStatus.RUNNING, TaskStatus.STOPPED, TaskStatus.NEVER_RAN]),
updates: PropTypes.arrayOf(PropTypes.shape({
taskState: PropTypes.string
})),
cleanupType: PropTypes.string,
};

export default TaskState;
9 changes: 9 additions & 0 deletions SingularityUI/app/components/taskDetail/TaskStatus.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const RUNNING = 'RUNNING';
const STOPPED = 'STOPPED';
const NEVER_RAN = 'NEVER_RAN';

export default {
RUNNING,
STOPPED,
NEVER_RAN
};

0 comments on commit 389be84

Please sign in to comment.