diff --git a/ansi.nomad b/ansi.nomad
deleted file mode 100644
index 1a70ace62..000000000
--- a/ansi.nomad
+++ /dev/null
@@ -1,17 +0,0 @@
-job "ansi-test" {
- datacenters = ["dc1"]
- type = "service"
-
- group "ansi-test" {
- count = 1
-
- task "ansi-test" {
- driver = "raw_exec"
-
- config {
- command = "node"
- args = [ "/Users/michael/work/ansi-test/index.js" ]
- }
- }
- }
-}
diff --git a/ui/app/controllers/jobs/job/index.js b/ui/app/controllers/jobs/job/index.js
index 2738cccf1..6e840df3e 100644
--- a/ui/app/controllers/jobs/job/index.js
+++ b/ui/app/controllers/jobs/job/index.js
@@ -30,10 +30,6 @@ export default Controller.extend(Sortable, WithNamespaceResetting, {
listToSort: computed.alias('taskGroups'),
sortedTaskGroups: computed.alias('listSorted'),
- sortedEvaluations: computed('model.evaluations.@each.modifyIndex', function() {
- return (this.get('model.evaluations') || []).sortBy('modifyIndex').reverse();
- }),
-
actions: {
gotoTaskGroup(taskGroup) {
this.transitionToRoute('jobs.job.task-group', taskGroup.get('job'), taskGroup);
diff --git a/ui/app/models/evaluation.js b/ui/app/models/evaluation.js
deleted file mode 100644
index 8afdf15ae..000000000
--- a/ui/app/models/evaluation.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import Ember from 'ember';
-import Model from 'ember-data/model';
-import attr from 'ember-data/attr';
-import { belongsTo } from 'ember-data/relationships';
-import { fragmentArray } from 'ember-data-model-fragments/attributes';
-import shortUUIDProperty from '../utils/properties/short-uuid';
-
-const { computed } = Ember;
-
-export default Model.extend({
- shortId: shortUUIDProperty('id'),
- priority: attr('number'),
- type: attr('string'),
- triggeredBy: attr('string'),
- status: attr('string'),
- statusDescription: attr('string'),
- failedTGAllocs: fragmentArray('placement-failure', { defaultValue: () => [] }),
-
- hasPlacementFailures: computed.bool('failedTGAllocs.length'),
-
- // TEMPORARY: https://github.com/emberjs/data/issues/5209
- originalJobId: attr('string'),
-
- job: belongsTo('job'),
-
- modifyIndex: attr('number'),
-});
diff --git a/ui/app/models/job.js b/ui/app/models/job.js
index 4f33983ac..18d74b8ff 100644
--- a/ui/app/models/job.js
+++ b/ui/app/models/job.js
@@ -53,35 +53,8 @@ export default Model.extend({
versions: hasMany('job-versions'),
allocations: hasMany('allocations'),
deployments: hasMany('deployments'),
- evaluations: hasMany('evaluations'),
namespace: belongsTo('namespace'),
- hasPlacementFailures: computed.bool('latestFailureEvaluation'),
-
- latestEvaluation: computed('evaluations.@each.modifyIndex', 'evaluations.isPending', function() {
- const evaluations = this.get('evaluations');
- if (!evaluations || evaluations.get('isPending')) {
- return null;
- }
- return evaluations.sortBy('modifyIndex').get('lastObject');
- }),
-
- latestFailureEvaluation: computed(
- 'evaluations.@each.modifyIndex',
- 'evaluations.isPending',
- function() {
- const evaluations = this.get('evaluations');
- if (!evaluations || evaluations.get('isPending')) {
- return null;
- }
-
- const failureEvaluations = evaluations.filterBy('hasPlacementFailures');
- if (failureEvaluations) {
- return failureEvaluations.sortBy('modifyIndex').get('lastObject');
- }
- }
- ),
-
supportsDeployments: computed.equal('type', 'service'),
runningDeployment: computed('deployments.@each.status', function() {
diff --git a/ui/app/models/placement-failure.js b/ui/app/models/placement-failure.js
deleted file mode 100644
index d711166b1..000000000
--- a/ui/app/models/placement-failure.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import attr from 'ember-data/attr';
-import Fragment from 'ember-data-model-fragments/fragment';
-
-export default Fragment.extend({
- name: attr('string'),
-
- coalescedFailures: attr('number'),
-
- nodesEvaluated: attr('number'),
- nodesExhausted: attr('number'),
-
- // Maps keyed by relevant dimension (dc, class, constraint, etc) with count values
- nodesAvailable: attr(),
- classFiltered: attr(),
- constraintFiltered: attr(),
- classExhausted: attr(),
- dimensionExhausted: attr(),
- quotaExhausted: attr(),
- scores: attr(),
-});
diff --git a/ui/app/models/task-group.js b/ui/app/models/task-group.js
index b3998a4cd..56e83d59a 100644
--- a/ui/app/models/task-group.js
+++ b/ui/app/models/task-group.js
@@ -24,11 +24,6 @@ export default Fragment.extend({
reservedEphemeralDisk: attr('number'),
- placementFailures: computed('job.latestFailureEvaluation.failedTGAllocs.[]', function() {
- const placementFailures = this.get('job.latestFailureEvaluation.failedTGAllocs');
- return placementFailures && placementFailures.findBy('name', this.get('name'));
- }),
-
queuedOrStartingAllocs: computed('summary.{queuedAllocs,startingAllocs}', function() {
return this.get('summary.queuedAllocs') + this.get('summary.startingAllocs');
}),
diff --git a/ui/app/routes/jobs/job.js b/ui/app/routes/jobs/job.js
index 4317a1e35..ae4c66ca1 100644
--- a/ui/app/routes/jobs/job.js
+++ b/ui/app/routes/jobs/job.js
@@ -1,7 +1,7 @@
import Ember from 'ember';
import notifyError from 'nomad-ui/utils/notify-error';
-const { Route, RSVP, inject } = Ember;
+const { Route, inject } = Ember;
export default Route.extend({
store: inject.service(),
@@ -17,7 +17,7 @@ export default Route.extend({
return this.get('store')
.findRecord('job', fullId, { reload: true })
.then(job => {
- return RSVP.all([job.get('allocations'), job.get('evaluations')]).then(() => job);
+ return job.get('allocations').then(() => job);
})
.catch(notifyError(this));
},
diff --git a/ui/app/serializers/evaluation.js b/ui/app/serializers/evaluation.js
deleted file mode 100644
index 76a2b9b3c..000000000
--- a/ui/app/serializers/evaluation.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import Ember from 'ember';
-import ApplicationSerializer from './application';
-
-const { inject, get, assign } = Ember;
-
-export default ApplicationSerializer.extend({
- system: inject.service(),
-
- normalize(typeHash, hash) {
- hash.FailedTGAllocs = Object.keys(hash.FailedTGAllocs || {}).map(key => {
- return assign({ Name: key }, get(hash, `FailedTGAllocs.${key}`) || {});
- });
-
- hash.PlainJobId = hash.JobID;
- hash.Namespace =
- hash.Namespace ||
- get(hash, 'Job.Namespace') ||
- this.get('system.activeNamespace.id') ||
- 'default';
- hash.JobID = JSON.stringify([hash.JobID, hash.Namespace]);
-
- // TEMPORARY: https://github.com/emberjs/data/issues/5209
- hash.OriginalJobId = hash.JobID;
-
- return this._super(typeHash, hash);
- },
-});
diff --git a/ui/app/serializers/job.js b/ui/app/serializers/job.js
index 74eeb78b0..0f36f7524 100644
--- a/ui/app/serializers/job.js
+++ b/ui/app/serializers/job.js
@@ -19,7 +19,7 @@ export default ApplicationSerializer.extend({
// Transform the map-based JobSummary object into an array-based
// JobSummary fragment list
hash.TaskGroupSummaries = Object.keys(get(hash, 'JobSummary.Summary') || {}).map(key => {
- const allocStats = get(hash, `JobSummary.Summary.${key}`) || {};
+ const allocStats = get(hash, `JobSummary.Summary.${key}`);
const summary = { Name: key };
Object.keys(allocStats).forEach(
@@ -65,11 +65,6 @@ export default ApplicationSerializer.extend({
related: buildURL(`${jobURL}/deployments`, { namespace: namespace }),
},
},
- evaluations: {
- links: {
- related: buildURL(`${jobURL}/evaluations`, { namespace: namespace }),
- },
- },
});
},
});
diff --git a/ui/app/styles/components.scss b/ui/app/styles/components.scss
index cb2162c2f..0b4545c21 100644
--- a/ui/app/styles/components.scss
+++ b/ui/app/styles/components.scss
@@ -12,7 +12,6 @@
@import "./components/loading-spinner";
@import "./components/metrics";
@import "./components/node-status-light";
-@import "./components/simple-list";
@import "./components/status-text";
@import "./components/timeline";
@import "./components/tooltip";
diff --git a/ui/app/styles/components/simple-list.scss b/ui/app/styles/components/simple-list.scss
deleted file mode 100644
index b3c962fd5..000000000
--- a/ui/app/styles/components/simple-list.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.simple-list {
- list-style: disc;
- list-style-position: inside;
- margin-left: 1.5rem;
-
- li {
- margin-bottom: 0.5em;
- }
-}
diff --git a/ui/app/templates/jobs/job/index.hbs b/ui/app/templates/jobs/job/index.hbs
index 07a83d98f..f740bca74 100644
--- a/ui/app/templates/jobs/job/index.hbs
+++ b/ui/app/templates/jobs/job/index.hbs
@@ -47,57 +47,6 @@
- {{#if model.hasPlacementFailures}}
-
-
- Placement Failures
-
-
- {{#each model.taskGroups as |taskGroup|}}
- {{#if taskGroup.placementFailures}}
- {{#with taskGroup.placementFailures as |failures|}}
-
- {{taskGroup.name}}
- {{inc failures.coalescedFailures}} unplaced
-
-
- {{#if (eq failures.nodesEvaluated 0)}}
- - No nodes were eligible for evaluation
- {{/if}}
- {{#each-in failures.nodesAvailable as |datacenter available|}}
- {{#if (eq available 0)}}
- - No nodes are available in datacenter {{datacenter}}
- {{/if}}
- {{/each-in}}
- {{#each-in failures.classFiltered as |class count|}}
- - Class {{class}} filtered {{count}} {{pluralize "node" count}}
- {{/each-in}}
- {{#each-in failures.constraintFiltered as |constraint count|}}
- - Constraint
{{constraint}}
filtered {{count}} {{pluralize "node" count}}
- {{/each-in}}
- {{#if failures.nodesExhausted}}
- - Resources exhausted on {{failures.nodesExhausted}} {{pluralize "node" failures.nodesExhausted}}
- {{/if}}
- {{#each-in failures.classExhausted as |class count|}}
- - Class {{class}} exhausted on {{count}} {{pluralize "node" count}}
- {{/each-in}}
- {{#each-in failures.dimensionExhausted as |dimension count|}}
- - Dimension {{dimension}} exhausted on {{count}} {{pluralize "node" count}}
- {{/each-in}}
- {{#each-in failures.quotaExhausted as |quota dimension|}}
- - Quota limit hit {{dimension}}
- {{/each-in}}
- {{#each-in failures.scores as |name score|}}
- - Score {{name}} = {{score}}
- {{/each-in}}
-
- {{/with}}
- {{/if}}
- {{/each}}
-
-
- {{/if}}
-
{{#if model.runningDeployment}}
@@ -160,39 +109,5 @@
{{/list-pagination}}
-
-
-
- Evaluations
-
-
- {{#list-table source=sortedEvaluations as |t|}}
- {{#t.head}}
-
ID |
- Priority |
- Triggered By |
- Status |
- Placement Failures |
- {{/t.head}}
- {{#t.body as |row|}}
-
- {{row.model.shortId}} |
- {{row.model.priority}} |
- {{row.model.triggeredBy}} |
- {{row.model.status}} |
-
- {{#if (eq row.model.status "blocked")}}
- N/A - In Progress
- {{else if row.model.hasPlacementFailures}}
- True
- {{else}}
- False
- {{/if}}
- |
-
- {{/t.body}}
- {{/list-table}}
-
-
{{/gutter-menu}}
diff --git a/ui/mirage/common.js b/ui/mirage/common.js
index 75416b593..c9c5de517 100644
--- a/ui/mirage/common.js
+++ b/ui/mirage/common.js
@@ -71,7 +71,7 @@ function ipv6() {
for (var i = 0; i < 8; i++) {
var subnet = [];
for (var char = 0; char < 4; char++) {
- subnet.push(faker.random.number(15).toString(16));
+ subnet.push(faker.random.number(16).toString(16));
}
subnets.push(subnet.join(''));
}
diff --git a/ui/mirage/config.js b/ui/mirage/config.js
index dd23a35e7..64bbcea41 100644
--- a/ui/mirage/config.js
+++ b/ui/mirage/config.js
@@ -59,12 +59,6 @@ export default function() {
this.get('/deployment/:id');
- this.get('/job/:id/evaluations', function({ evaluations }, { params }) {
- return this.serialize(evaluations.where({ jobId: params.id }));
- });
-
- this.get('/evaluation/:id');
-
this.get('/deployment/allocations/:id', function(schema, { params }) {
const job = schema.jobs.find(schema.deployments.find(params.id).jobId);
const allocations = schema.allocations.where({ jobId: job.id });
diff --git a/ui/mirage/factories/evaluation.js b/ui/mirage/factories/evaluation.js
deleted file mode 100644
index 98cb7c03e..000000000
--- a/ui/mirage/factories/evaluation.js
+++ /dev/null
@@ -1,110 +0,0 @@
-import Ember from 'ember';
-import { Factory, faker, trait } from 'ember-cli-mirage';
-import { provide, pickOne } from '../utils';
-import { DATACENTERS } from '../common';
-
-const EVAL_TYPES = ['system', 'service', 'batch'];
-const EVAL_STATUSES = ['blocked', 'pending', 'complete', 'failed', 'canceled'];
-const EVAL_TRIGGERED_BY = [
- 'job-register',
- 'job-deregister',
- 'periodic-job',
- 'node-update',
- 'scheduled',
- 'roling-update',
- 'deployment-watcher',
- 'failed-follow-up',
- 'max-plan-attempts',
-];
-
-const generateCountMap = (keysCount, list) => () => {
- const sample = Array(keysCount)
- .fill(null)
- .map(() => pickOne(list))
- .uniq();
- return sample.reduce((hash, key) => {
- hash[key] = faker.random.number({ min: 1, max: 5 });
- return hash;
- }, {});
-};
-
-const generateNodesAvailable = generateCountMap(5, DATACENTERS);
-const generateClassFiltered = generateCountMap(3, provide(10, faker.hacker.abbreviation));
-const generateClassExhausted = generateClassFiltered;
-const generateDimensionExhausted = generateCountMap(1, ['cpu', 'mem', 'disk', 'iops']);
-const generateQuotaExhausted = generateDimensionExhausted;
-const generateScores = generateCountMap(1, ['binpack', 'job-anti-affinity']);
-const generateConstraintFiltered = generateCountMap(2, [
- 'prop = val',
- 'driver = docker',
- 'arch = x64',
-]);
-
-export default Factory.extend({
- id: () => faker.random.uuid(),
-
- priority: () => faker.random.number(100),
-
- type: faker.list.random(...EVAL_TYPES),
- triggeredBy: faker.list.random(...EVAL_TRIGGERED_BY),
- status: faker.list.random(...EVAL_STATUSES),
- statusDescription: () => faker.lorem.sentence(),
-
- failedTGAllocs: null,
-
- modifyIndex: () => faker.random.number({ min: 10, max: 2000 }),
-
- withPlacementFailures: trait({
- status: faker.list.random(...EVAL_STATUSES.without('blocked')),
- afterCreate(evaluation, server) {
- assignJob(evaluation, server);
- const taskGroups = server.db.taskGroups.where({ jobId: evaluation.jobId });
-
- const taskGroupNames = taskGroups.mapBy('name');
- const failedTaskGroupsCount = faker.random.number({ min: 1, max: taskGroupNames.length });
- const failedTaskGroupNames = [];
- for (let i = 0; i < failedTaskGroupsCount; i++) {
- failedTaskGroupNames.push(
- ...taskGroupNames.splice(faker.random.number(taskGroupNames.length), 1)
- );
- }
-
- const placementFailures = failedTaskGroupNames.reduce((hash, name) => {
- hash[name] = {
- CoalescedFailures: faker.random.number({ min: 1, max: 20 }),
- NodesEvaluated: faker.random.number({ min: 1, max: 100 }),
- NodesExhausted: faker.random.number({ min: 1, max: 100 }),
-
- NodesAvailable: Math.random() > 0.7 ? generateNodesAvailable() : null,
- ClassFiltered: Math.random() > 0.7 ? generateClassFiltered() : null,
- ConstraintFiltered: Math.random() > 0.7 ? generateConstraintFiltered() : null,
- ClassExhausted: Math.random() > 0.7 ? generateClassExhausted() : null,
- DimensionExhausted: Math.random() > 0.7 ? generateDimensionExhausted() : null,
- QuotaExhausted: Math.random() > 0.7 ? generateQuotaExhausted() : null,
- Scores: Math.random() > 0.7 ? generateScores() : null,
- };
- return hash;
- }, {});
-
- evaluation.update({
- failedTGAllocs: placementFailures,
- });
- },
- }),
-
- afterCreate(evaluation, server) {
- assignJob(evaluation, server);
- },
-});
-
-function assignJob(evaluation, server) {
- Ember.assert(
- '[Mirage] No jobs! make sure jobs are created before evaluations',
- server.db.jobs.length
- );
-
- const job = evaluation.jobId ? server.db.jobs.find(evaluation.jobId) : pickOne(server.db.jobs);
- evaluation.update({
- jobId: job.id,
- });
-}
diff --git a/ui/mirage/factories/job.js b/ui/mirage/factories/job.js
index b18d16d71..eee780e47 100644
--- a/ui/mirage/factories/job.js
+++ b/ui/mirage/factories/job.js
@@ -14,7 +14,7 @@ export default Factory.extend({
region: () => 'global',
type: faker.list.random(...JOB_TYPES),
- priority: () => faker.random.number(100),
+ priority: () => faker.random.number(200),
all_at_once: faker.random.boolean,
status: faker.list.random(...JOB_STATUSES),
datacenters: provider(
@@ -41,12 +41,6 @@ export default Factory.extend({
// When true, deployments for the job will always have a 'running' status
activeDeployment: false,
- // When true, an evaluation with a high modify index and placement failures is created
- failedPlacements: false,
-
- // When true, no evaluations have failed placements
- noFailedPlacements: false,
-
afterCreate(job, server) {
const groups = server.createList('task-group', job.groupsCount, {
job,
@@ -90,17 +84,5 @@ export default Factory.extend({
activeDeployment: job.activeDeployment,
});
});
-
- server.createList('evaluation', faker.random.number({ min: 1, max: 5 }), { job });
- if (!job.noFailedPlacements) {
- server.createList('evaluation', faker.random.number(3), 'withPlacementFailures', { job });
- }
-
- if (job.failedPlacements) {
- server.create('evaluation', 'withPlacementFailures', {
- job,
- modifyIndex: 4000,
- });
- }
},
});
diff --git a/ui/mirage/scenarios/default.js b/ui/mirage/scenarios/default.js
index 7ab761099..700d96b90 100644
--- a/ui/mirage/scenarios/default.js
+++ b/ui/mirage/scenarios/default.js
@@ -4,8 +4,7 @@ export default function(server) {
server.createList('namespace', 3);
- server.createList('job', 10);
- server.createList('job', 5, { failedPlacements: true });
+ server.createList('job', 15);
server.createList('token', 3);
logTokens(server);
diff --git a/ui/tests/acceptance/job-detail-test.js b/ui/tests/acceptance/job-detail-test.js
index cf3b1bcc5..512c572e4 100644
--- a/ui/tests/acceptance/job-detail-test.js
+++ b/ui/tests/acceptance/job-detail-test.js
@@ -296,83 +296,6 @@ test('the active deployment section can be expanded to show task groups and allo
});
});
-test('the evaluations table lists evaluations sorted by modify index', function(assert) {
- job = server.create('job');
- const evaluations = server.db.evaluations
- .where({ jobId: job.id })
- .sortBy('modifyIndex')
- .reverse();
-
- visit(`/jobs/${job.id}`);
-
- andThen(() => {
- assert.equal(
- findAll('.evaluations tbody tr').length,
- evaluations.length,
- 'A row for each evaluation'
- );
-
- evaluations.forEach((evaluation, index) => {
- const row = $(findAll('.evaluations tbody tr')[index]);
- assert.equal(
- row.find('td:eq(0)').text(),
- evaluation.id.split('-')[0],
- `Short ID, row ${index}`
- );
- });
-
- const firstEvaluation = evaluations[0];
- const row = $(findAll('.evaluations tbody tr')[0]);
- assert.equal(row.find('td:eq(1)').text(), '' + firstEvaluation.priority, 'Priority');
- assert.equal(row.find('td:eq(2)').text(), firstEvaluation.triggeredBy, 'Triggered By');
- assert.equal(row.find('td:eq(3)').text(), firstEvaluation.status, 'Status');
- });
-});
-
-test('when the job has placement failures, they are called out', function(assert) {
- job = server.create('job', { failedPlacements: true });
- const failedEvaluation = server.db.evaluations
- .where({ jobId: job.id })
- .filter(evaluation => evaluation.failedTGAllocs)
- .sortBy('modifyIndex')
- .reverse()[0];
-
- const failedTaskGroupNames = Object.keys(failedEvaluation.failedTGAllocs);
-
- visit(`/jobs/${job.id}`);
-
- andThen(() => {
- assert.ok(find('.placement-failures'), 'Placement failures section found');
-
- const taskGroupLabels = findAll('.placement-failures h3.title').map(title =>
- title.textContent.trim()
- );
- failedTaskGroupNames.forEach(name => {
- assert.ok(
- taskGroupLabels.find(label => label.includes(name)),
- `${name} included in placement failures list`
- );
- assert.ok(
- taskGroupLabels.find(label =>
- label.includes(failedEvaluation.failedTGAllocs[name].CoalescedFailures + 1)
- ),
- 'The number of unplaced allocs = CoalescedFailures + 1'
- );
- });
- });
-});
-
-test('when the job has no placement failures, the placement failures section is gone', function(
- assert
-) {
- job = server.create('job', { noFailedPlacements: true });
- visit(`/jobs/${job.id}`);
-
- andThen(() => {
- assert.notOk(find('.placement-failures'), 'Placement failures section not found');
- });
-});
-
test('when the job is not found, an error message is shown, but the URL persists', function(
assert
) {