You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by dm...@apache.org on 2017/10/18 23:21:45 UTC
aurora git commit: Add cron configuration to Job Page
Repository: aurora
Updated Branches:
refs/heads/master 4f52f754f -> c6388774b
Add cron configuration to Job Page
Reviewed at https://reviews.apache.org/r/63125/
Project: http://git-wip-us.apache.org/repos/asf/aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/c6388774
Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/c6388774
Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/c6388774
Branch: refs/heads/master
Commit: c6388774ba2eef7bed18668c8c735d6134d22e80
Parents: 4f52f75
Author: David McLaughlin <da...@dmclaughlin.com>
Authored: Wed Oct 18 16:16:21 2017 -0700
Committer: David McLaughlin <da...@dmclaughlin.com>
Committed: Wed Oct 18 16:16:21 2017 -0700
----------------------------------------------------------------------
ui/.eslintrc | 1 +
ui/src/main/js/components/JobConfig.js | 18 ++-
ui/src/main/js/components/TaskConfigSummary.js | 110 +++++++++++++++----
.../js/components/__tests__/JobConfig-test.js | 11 +-
ui/src/main/js/pages/Job.js | 23 +++-
ui/src/main/js/pages/__tests__/Job-test.js | 3 +-
ui/src/main/js/utils/Thrift.js | 1 +
ui/src/main/sass/components/_job-page.scss | 4 +
ui/test-setup.js | 6 +
9 files changed, 144 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/.eslintrc
----------------------------------------------------------------------
diff --git a/ui/.eslintrc b/ui/.eslintrc
index f7ac075..5cdc4e6 100644
--- a/ui/.eslintrc
+++ b/ui/.eslintrc
@@ -11,6 +11,7 @@
"globals": {
"ACTIVE_STATES": true,
"ACTIVE_JOB_UPDATE_STATES": true,
+ "CronCollisionPolicy": true,
"JobKey": true,
"JobUpdateAction": true,
"JobUpdateKey": true,
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/src/main/js/components/JobConfig.js
----------------------------------------------------------------------
diff --git a/ui/src/main/js/components/JobConfig.js b/ui/src/main/js/components/JobConfig.js
index 275f46a..0bce57c 100644
--- a/ui/src/main/js/components/JobConfig.js
+++ b/ui/src/main/js/components/JobConfig.js
@@ -2,15 +2,27 @@ import React from 'react';
import ConfigDiff from 'components/ConfigDiff';
import Loading from 'components/Loading';
-import TaskConfigSummary from 'components/TaskConfigSummary';
+import TaskConfigSummary, { CronConfigSummary } from 'components/TaskConfigSummary';
import { isNully, sort } from 'utils/Common';
-export default function JobConfig({ groups }) {
- if (isNully(groups)) {
+export function CronJobConfig({ cronJob }) {
+ return (<div className='job-configuration'>
+ <div className='job-configuration-summaries'>
+ <CronConfigSummary cronJob={cronJob} />
+ </div>
+ </div>);
+}
+
+export default function JobConfig({ cronJob, groups }) {
+ if (isNully(groups) && isNully(cronJob)) {
return <Loading />;
}
+ if (!isNully(cronJob)) {
+ return <CronJobConfig cronJob={cronJob} />;
+ }
+
const sorted = sort(groups, (g) => g.instances[0].first);
return (<div className='job-configuration'>
<div className='job-configuration-summaries'>
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/src/main/js/components/TaskConfigSummary.js
----------------------------------------------------------------------
diff --git a/ui/src/main/js/components/TaskConfigSummary.js b/ui/src/main/js/components/TaskConfigSummary.js
index 5c00d1e..2a325d9 100644
--- a/ui/src/main/js/components/TaskConfigSummary.js
+++ b/ui/src/main/js/components/TaskConfigSummary.js
@@ -1,40 +1,107 @@
+import moment from 'moment';
import React from 'react';
+import { RelativeTime } from 'components/Time';
+
import { constraintToString, getResource, getResources, instanceRangeToString } from 'utils/Task';
+import { COLLISION_POLICY } from 'utils/Thrift';
-export default function TaskConfigSummary({ config, instances }) {
- return (<table className='table table-bordered task-config-summary'>
+// ESLint doesn't like React's new adjacent elements, so we need to disable it here
+/* eslint-disable */
+function Resources({ config }) {
+ return [<tr>
+ <th rowSpan='4'>Resources</th>
+ <td>cpus</td>
+ <td>{getResource(config.resources, 'numCpus').numCpus}</td>
+ </tr>,
+ <tr>
+ <td>ram</td>
+ <td>{getResource(config.resources, 'ramMb').ramMb}</td>
+ </tr>,
+ <tr>
+ <td>disk</td>
+ <td>{getResource(config.resources, 'diskMb').diskMb}</td>
+ </tr>,
+ <tr>
+ <td>ports</td>
+ <td>{getResources(config.resources, 'namedPort').map((r) => r.namedPort).join(', ')}</td>
+ </tr>];
+}
+/* eslint-enable */
+
+function Constraints({ config }) {
+ return (<tr>
+ <th>Constraints</th>
+ <td colSpan='2'>
+ {config.constraints.map((t) => (<span className='task-constraint' key={t.name}>
+ {t.name}: {constraintToString(t.constraint)}
+ </span>))}
+ </td>
+ </tr>);
+}
+
+function Metadata({ config }) {
+ return (<tr>
+ <th>Metadata</th>
+ <td colSpan='2'>
+ {config.metadata.map((m, i) => <span key={`${m.key}-${i}`}>{m.key}: {m.value}</span>)}
+ </td>
+ </tr>);
+}
+
+export function CronConfigSummary({ cronJob }) {
+ const config = cronJob.job.taskConfig;
+ return (<table className='table table-bordered task-config-summary cron-config-summary'>
<tbody>
<tr>
<th colSpan='100%'>
- Configuration for instance {instanceRangeToString(instances)}
+ Cron Job Configuration
</th>
</tr>
<tr>
- <th rowSpan='4'>Resources</th>
- <td>cpus</td>
- <td>{getResource(config.resources, 'numCpus').numCpus}</td>
+ <th>Cron Schedule</th>
+ <td colSpan='2'>{cronJob.job.cronSchedule}</td>
</tr>
<tr>
- <td>ram</td>
- <td>{getResource(config.resources, 'ramMb').ramMb}</td>
+ <th>Collision Policy</th>
+ <td colSpan='2'>{COLLISION_POLICY[cronJob.job.cronCollisionPolicy]}</td>
</tr>
<tr>
- <td>disk</td>
- <td>{getResource(config.resources, 'diskMb').diskMb}</td>
+ <th>Next Cron Run</th>
+ <td colSpan='2'>
+ {moment(cronJob.nextCronRunMs).format('MMMM Do YYYY, h:mm:ss a')} UTC (
+ <RelativeTime ts={cronJob.nextCronRunMs} />)
+ </td>
</tr>
<tr>
- <td>ports</td>
- <td>{getResources(config.resources, 'namedPort').map((r) => r.namedPort).join(', ')}</td>
+ <th># Instances</th>
+ <td colSpan='2'>{cronJob.job.instanceCount}</td>
</tr>
+ <Resources config={config} />
+ <Constraints config={config} />
<tr>
- <th>Constraints</th>
- <td colSpan='2'>
- {config.constraints.map((t) => (<span className='task-constraint' key={t.name}>
- {t.name}: {constraintToString(t.constraint)}
- </span>))}
- </td>
+ <th>Tier</th>
+ <td colSpan='2'>{config.tier}</td>
+ </tr>
+ <Metadata config={config} />
+ <tr>
+ <th>Contact</th>
+ <td colSpan='2'>{config.contactEmail}</td>
+ </tr>
+ </tbody>
+ </table>);
+}
+
+export default function TaskConfigSummary({ config, instances }) {
+ return (<table className='table table-bordered task-config-summary'>
+ <tbody>
+ <tr>
+ <th colSpan='100%'>
+ Configuration for instance {instanceRangeToString(instances)}
+ </th>
</tr>
+ <Resources config={config} />
+ <Constraints config={config} />
<tr>
<th>Tier</th>
<td colSpan='2'>{config.tier}</td>
@@ -43,12 +110,7 @@ export default function TaskConfigSummary({ config, instances }) {
<th>Service</th>
<td colSpan='2'>{config.isService ? 'true' : 'false'}</td>
</tr>
- <tr>
- <th>Metadata</th>
- <td colSpan='2'>
- {config.metadata.map((m, i) => <span key={`${m.key}-${i}`}>{m.key}: {m.value}</span>)}
- </td>
- </tr>
+ <Metadata config={config} />
<tr>
<th>Contact</th>
<td colSpan='2'>{config.contactEmail}</td>
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/src/main/js/components/__tests__/JobConfig-test.js
----------------------------------------------------------------------
diff --git a/ui/src/main/js/components/__tests__/JobConfig-test.js b/ui/src/main/js/components/__tests__/JobConfig-test.js
index 59541d9..cd1b7a0 100644
--- a/ui/src/main/js/components/__tests__/JobConfig-test.js
+++ b/ui/src/main/js/components/__tests__/JobConfig-test.js
@@ -2,10 +2,11 @@ import React from 'react';
import { shallow } from 'enzyme';
import ConfigDiff from '../ConfigDiff';
-import JobConfig from '../JobConfig';
+import JobConfig, { CronJobConfig } from '../JobConfig';
import Loading from '../Loading';
import TaskConfigSummary from '../TaskConfigSummary';
+import { JobSummaryBuilder } from 'test-utils/JobBuilders';
import { TaskConfigBuilder, createConfigGroup } from 'test-utils/TaskBuilders';
describe('JobConfig', () => {
@@ -20,8 +21,14 @@ describe('JobConfig', () => {
expect(el.contains(<ConfigDiff groups={[group0, group1, group2]} />)).toBe(true);
});
- it('Should render Loading when no groups are supplied', () => {
+ it('Should render Loading when no groups or cronJob are supplied', () => {
const el = shallow(<JobConfig />);
expect(el.contains(<Loading />)).toBe(true);
});
+
+ it('Should render CronJobConfig when cronJob is supplied', () => {
+ const cron = JobSummaryBuilder.build();
+ const el = shallow(<JobConfig cronJob={cron} />);
+ expect(el.contains(<CronJobConfig cronJob={cron} />)).toBe(true);
+ });
});
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/src/main/js/pages/Job.js
----------------------------------------------------------------------
diff --git a/ui/src/main/js/pages/Job.js b/ui/src/main/js/pages/Job.js
index 6a9bd7e..070f1e4 100644
--- a/ui/src/main/js/pages/Job.js
+++ b/ui/src/main/js/pages/Job.js
@@ -27,7 +27,8 @@ export default class Job extends React.Component {
configGroups: props.configGroups,
tasks: props.tasks,
updates: props.updates,
- pendingReasons: props.pendingReasons
+ pendingReasons: props.pendingReasons,
+ cronJob: props.cronJob
};
}
@@ -58,6 +59,20 @@ export default class Job extends React.Component {
configGroups: response.result.configSummaryResult.summary.groups
});
});
+ api.getJobSummary(role, (response) => {
+ const cronJob = response.result.jobSummaryResult.summaries.find((j) => {
+ return j.job.key.environment === that.props.match.params.environment &&
+ j.job.key.name === that.props.match.params.name &&
+ !isNully(j.job.cronSchedule);
+ });
+
+ if (cronJob) {
+ that.setState({
+ cluster: response.serverInfo.clusterName,
+ cronJob
+ });
+ }
+ });
const updateQuery = new JobUpdateQuery();
updateQuery.jobKey = key;
@@ -123,7 +138,9 @@ export default class Job extends React.Component {
jobStatusTab() {
const activeTasks = sort(this.state.tasks.filter(isActive), (t) => t.assignedTask.instanceId);
- const numberConfigs = isNully(this.state.configGroups) ? '' : this.state.configGroups.length;
+ const numberConfigs = isNully(this.state.cronJob)
+ ? isNully(this.state.configGroups) ? '' : this.state.configGroups.length
+ : 1;
return {
id: JOB_STATUS_TAB,
name: 'Job Status',
@@ -143,7 +160,7 @@ export default class Job extends React.Component {
icon: 'info-sign',
id: TASK_CONFIG_TAB,
name: `Configuration (${numberConfigs})`,
- content: <JobConfig groups={this.state.configGroups} />
+ content: <JobConfig cronJob={this.state.cronJob} groups={this.state.configGroups} />
}]} />
</PanelGroup>)
};
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/src/main/js/pages/__tests__/Job-test.js
----------------------------------------------------------------------
diff --git a/ui/src/main/js/pages/__tests__/Job-test.js b/ui/src/main/js/pages/__tests__/Job-test.js
index 09dd54e..03ef20d 100644
--- a/ui/src/main/js/pages/__tests__/Job-test.js
+++ b/ui/src/main/js/pages/__tests__/Job-test.js
@@ -23,7 +23,8 @@ function apiSpy() {
getTasksWithoutConfigs: jest.fn(),
getPendingReason: jest.fn(),
getConfigSummary: jest.fn(),
- getJobUpdateDetails: jest.fn()
+ getJobUpdateDetails: jest.fn(),
+ getJobSummary: jest.fn()
};
}
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/src/main/js/utils/Thrift.js
----------------------------------------------------------------------
diff --git a/ui/src/main/js/utils/Thrift.js b/ui/src/main/js/utils/Thrift.js
index 4336bd1..a097037 100644
--- a/ui/src/main/js/utils/Thrift.js
+++ b/ui/src/main/js/utils/Thrift.js
@@ -3,6 +3,7 @@ import { invert } from 'utils/Common';
export const SCHEDULE_STATUS = invert(ScheduleStatus);
export const UPDATE_STATUS = invert(JobUpdateStatus);
export const UPDATE_ACTION = invert(JobUpdateAction);
+export const COLLISION_POLICY = invert(CronCollisionPolicy);
export const OKAY_SCHEDULE_STATUS = [
ScheduleStatus.RUNNING,
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/src/main/sass/components/_job-page.scss
----------------------------------------------------------------------
diff --git a/ui/src/main/sass/components/_job-page.scss b/ui/src/main/sass/components/_job-page.scss
index cd03832..91b731f 100644
--- a/ui/src/main/sass/components/_job-page.scss
+++ b/ui/src/main/sass/components/_job-page.scss
@@ -68,6 +68,10 @@
}
}
+ .cron-config-summary {
+ width: 500px !important;
+ }
+
tr:first-child {
background-color: $grid_color;
}
http://git-wip-us.apache.org/repos/asf/aurora/blob/c6388774/ui/test-setup.js
----------------------------------------------------------------------
diff --git a/ui/test-setup.js b/ui/test-setup.js
index a86a89a..5b739de 100644
--- a/ui/test-setup.js
+++ b/ui/test-setup.js
@@ -64,3 +64,9 @@ global.JobUpdateAction = {
'INSTANCE_UPDATE_FAILED' : 5,
'INSTANCE_ROLLBACK_FAILED' : 6
};
+
+global.CronCollisionPolicy = {
+ 'KILL_EXISTING': 0,
+ 'CANCEL_NEW': 1,
+ 'RUN_OVERLAP': 2
+};