open-nomad/ui/app/models/allocation.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

229 lines
6 KiB
JavaScript
Raw Normal View History

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { equal, none } from '@ember/object/computed';
import Model from '@ember-data/model';
import { attr, belongsTo, hasMany } from '@ember-data/model';
2017-09-19 14:47:10 +00:00
import { fragment, fragmentArray } from 'ember-data-model-fragments/attributes';
import isEqual from 'lodash.isequal';
import intersection from 'lodash.intersection';
2017-09-19 14:47:10 +00:00
import shortUUIDProperty from '../utils/properties/short-uuid';
import classic from 'ember-classic-decorator';
2017-09-19 14:47:10 +00:00
const STATUS_ORDER = {
pending: 1,
running: 2,
complete: 3,
unknown: 4,
failed: 5,
lost: 6,
};
@classic
export default class Allocation extends Model {
@service token;
@service store;
@shortUUIDProperty('id') shortId;
@belongsTo('job') job;
@belongsTo('node') node;
@attr('string') namespace;
@attr('string') nodeID;
@attr('string') name;
@attr('string') taskGroupName;
@fragment('resources') resources;
@fragment('resources') allocatedResources;
@attr('number') jobVersion;
2018-07-19 20:31:39 +00:00
@attr('number') modifyIndex;
@attr('date') modifyTime;
2018-07-19 20:31:39 +00:00
@attr('number') createIndex;
@attr('date') createTime;
2017-09-19 14:47:10 +00:00
@attr('string') clientStatus;
@attr('string') desiredStatus;
@attr() desiredTransition;
[ui, feature] Job Page Redesign (#16932) * [ui] Service job status panel (#16134) * it begins * Hacky demo enabled * Still very hacky but seems deece * Floor of at least 3 must be shown * Width from on-high * Other statuses considered * More sensible allocTypes listing * Beginnings of a legend * Total number of allocs running now maps over job.groups * Lintfix * base the number of slots to hold open on actual tallies, which should never exceed totalAllocs * Versions get yer versions here * Versions lookin like versions * Mirage fixup * Adds Remaining as an alloc chart status and adds historical status option * Get tests passing again by making job status static for a sec * Historical status panel click actions moved into their own component class * job detail tests plz chill * Testing if percy is fickle * Hyper-specfic on summary distribution bar identifier * Perhaps the 2nd allocSummary item no longer exists with the more accurate afterCreate data * UI Test eschewing the page pattern * Bones of a new acceptance test * Track width changes explicitly with window-resize * testlintfix * Alloc counting tests * Alloc grouping test * Alloc grouping with complex resizing * Refined the list of showable statuses * PR feedback addressed * renamed allocation-row to allocation-status-row * [ui, job status] Make panel status mode a queryParam (#16345) * queryParam changing * Test for QP in panel * Adding @tracked to legacy controller * Move the job of switching to Historical out to larger context * integration test mock passed func * [ui] Service job deployment status panel (#16383) * A very fast and loose deployment panel * Removing Unknown status from the panel * Set up oldAllocs list in constructor, rather than as a getter/tracked var * Small amount of template cleanup * Refactored latest-deployment new logic back into panel.js * Revert now-unused latest-deployment component * margin bottom when ungrouped also * Basic integration tests for job deployment status panel * Updates complete alloc colour to green for new visualizations only (#16618) * Updates complete alloc colour to green for new visualizations only * Pale green instead of dark green for viz in general * [ui] Job Deployment Status: History and Update Props (#16518) * Deployment history wooooooo * Styled deployment history * Update Params * lintfix * Types and groups for updateParams * Live-updating history * Harden with types, error states, and pending states * Refactor updateParams to use trigger component * [ui] Deployment History search (#16608) * Functioning searchbox * Some nice animations for history items * History search test * Fixing up some old mirage conventions * some a11y rule override to account for scss keyframes * Split panel into deploying and steady components * HandleError passed from job index * gridified panel elements * TotalAllocs added to deploying.js * Width perc to px * [ui] Splitting deployment allocs by status, health, and canary status (#16766) * Initial attempt with lots of scratchpad work * Style mods per UI discussion * Fix canary overflow bug * Dont show canary or health for steady/prev-alloc blocks * Steady state * Thanks Julie * Fixes steady-state versions * Legen, wait for it... * Test fixes now that we have a minimum block size * PR prep * Shimmer effect on pending and unplaced allocs (#16801) * Shimmer effect on pending and unplaced * Dont show animation in the legend * [ui, deployments] Linking allocblocks and legends to allocation / allocations index routes (#16821) * Conditional link-to component and basic linking to allocations and allocation routes * Job versions filter added to allocations index page * Steady state legends link * Legend links * Badge count links for versions * Fix: faded class on steady-state legend items * version link now wont show completed ones * Fix a11y violations with link labels * Combining some template conditional logic * [ui, deployments] Conversions on long nanosecond update params (#16882) * Conversions on long nanosecond nums * Early return in updateParamGroups comp prop * [ui, deployments] Mirage Actively Deploying Job and Deployment Integration Tests (#16888) * Start of deployment alloc test scaffolding * Bit of test cleanup and canary for ungrouped allocs * Flakey but more robust integrations for deployment panel * De-flake acceptance tests and add an actively deploying job to mirage * Jitter-less alloc status distribution removes my bad math * bugfix caused by summary.desiredTotal non-null * More interesting mirage active deployment alloc breakdown * Further tests for previous-allocs row * Previous alloc legend tests * Percy snapshots added to integration test * changelog
2023-04-25 02:45:39 +00:00
@attr() deploymentStatus;
get isCanary() {
return this.deploymentStatus?.Canary;
}
// deploymentStatus.Healthy can be true, false, or null. Null implies pending
[ui, feature] Job Page Redesign (#16932) * [ui] Service job status panel (#16134) * it begins * Hacky demo enabled * Still very hacky but seems deece * Floor of at least 3 must be shown * Width from on-high * Other statuses considered * More sensible allocTypes listing * Beginnings of a legend * Total number of allocs running now maps over job.groups * Lintfix * base the number of slots to hold open on actual tallies, which should never exceed totalAllocs * Versions get yer versions here * Versions lookin like versions * Mirage fixup * Adds Remaining as an alloc chart status and adds historical status option * Get tests passing again by making job status static for a sec * Historical status panel click actions moved into their own component class * job detail tests plz chill * Testing if percy is fickle * Hyper-specfic on summary distribution bar identifier * Perhaps the 2nd allocSummary item no longer exists with the more accurate afterCreate data * UI Test eschewing the page pattern * Bones of a new acceptance test * Track width changes explicitly with window-resize * testlintfix * Alloc counting tests * Alloc grouping test * Alloc grouping with complex resizing * Refined the list of showable statuses * PR feedback addressed * renamed allocation-row to allocation-status-row * [ui, job status] Make panel status mode a queryParam (#16345) * queryParam changing * Test for QP in panel * Adding @tracked to legacy controller * Move the job of switching to Historical out to larger context * integration test mock passed func * [ui] Service job deployment status panel (#16383) * A very fast and loose deployment panel * Removing Unknown status from the panel * Set up oldAllocs list in constructor, rather than as a getter/tracked var * Small amount of template cleanup * Refactored latest-deployment new logic back into panel.js * Revert now-unused latest-deployment component * margin bottom when ungrouped also * Basic integration tests for job deployment status panel * Updates complete alloc colour to green for new visualizations only (#16618) * Updates complete alloc colour to green for new visualizations only * Pale green instead of dark green for viz in general * [ui] Job Deployment Status: History and Update Props (#16518) * Deployment history wooooooo * Styled deployment history * Update Params * lintfix * Types and groups for updateParams * Live-updating history * Harden with types, error states, and pending states * Refactor updateParams to use trigger component * [ui] Deployment History search (#16608) * Functioning searchbox * Some nice animations for history items * History search test * Fixing up some old mirage conventions * some a11y rule override to account for scss keyframes * Split panel into deploying and steady components * HandleError passed from job index * gridified panel elements * TotalAllocs added to deploying.js * Width perc to px * [ui] Splitting deployment allocs by status, health, and canary status (#16766) * Initial attempt with lots of scratchpad work * Style mods per UI discussion * Fix canary overflow bug * Dont show canary or health for steady/prev-alloc blocks * Steady state * Thanks Julie * Fixes steady-state versions * Legen, wait for it... * Test fixes now that we have a minimum block size * PR prep * Shimmer effect on pending and unplaced allocs (#16801) * Shimmer effect on pending and unplaced * Dont show animation in the legend * [ui, deployments] Linking allocblocks and legends to allocation / allocations index routes (#16821) * Conditional link-to component and basic linking to allocations and allocation routes * Job versions filter added to allocations index page * Steady state legends link * Legend links * Badge count links for versions * Fix: faded class on steady-state legend items * version link now wont show completed ones * Fix a11y violations with link labels * Combining some template conditional logic * [ui, deployments] Conversions on long nanosecond update params (#16882) * Conversions on long nanosecond nums * Early return in updateParamGroups comp prop * [ui, deployments] Mirage Actively Deploying Job and Deployment Integration Tests (#16888) * Start of deployment alloc test scaffolding * Bit of test cleanup and canary for ungrouped allocs * Flakey but more robust integrations for deployment panel * De-flake acceptance tests and add an actively deploying job to mirage * Jitter-less alloc status distribution removes my bad math * bugfix caused by summary.desiredTotal non-null * More interesting mirage active deployment alloc breakdown * Further tests for previous-allocs row * Previous alloc legend tests * Percy snapshots added to integration test * changelog
2023-04-25 02:45:39 +00:00
get isHealthy() {
return this.deploymentStatus?.Healthy;
}
get isUnhealthy() {
return this.deploymentStatus?.Healthy === false;
}
get willNotRestart() {
return this.clientStatus === 'failed' || this.clientStatus === 'lost';
}
get willNotReschedule() {
return (
this.willNotRestart &&
!this.get('nextAllocation.content') &&
!this.get('followUpEvaluation.content')
);
}
get hasBeenRescheduled() {
return this.get('followUpEvaluation.content');
}
get hasBeenRestarted() {
return this.states
.map((s) => s.events.content)
.flat()
.find((e) => e.type === 'Restarting');
}
@attr healthChecks;
async getServiceHealth() {
const data = await this.store.adapterFor('allocation').check(this);
// Compare Results
if (!isEqual(this.healthChecks, data)) {
this.set('healthChecks', data);
}
}
@computed('')
get plainJobId() {
return JSON.parse(this.belongsTo('job').id())[0];
}
@computed('clientStatus')
get statusIndex() {
2019-03-26 07:46:44 +00:00
return STATUS_ORDER[this.clientStatus] || 100;
}
2017-09-19 14:47:10 +00:00
@equal('clientStatus', 'running') isRunning;
@attr('boolean') isMigrating;
@computed('clientStatus')
get isScheduled() {
return ['pending', 'running'].includes(this.clientStatus);
}
// An allocation model created from any allocation list response will be lacking
// many properties (some of which can always be null). This is an indicator that
// the allocation needs to be reloaded to get the complete allocation state.
@none('allocationTaskGroup') isPartial;
2018-04-25 22:50:15 +00:00
// When allocations are server-side rescheduled, a paper trail
// is left linking all reschedule attempts.
@belongsTo('allocation', { inverse: 'nextAllocation' }) previousAllocation;
@belongsTo('allocation', { inverse: 'previousAllocation' }) nextAllocation;
2021-12-28 16:08:12 +00:00
@hasMany('allocation', { inverse: 'preemptedByAllocation' })
preemptedAllocations;
@belongsTo('allocation', { inverse: 'preemptedAllocations' })
preemptedByAllocation;
@attr('boolean') wasPreempted;
2019-04-16 19:11:43 +00:00
@belongsTo('evaluation') followUpEvaluation;
2018-04-25 22:50:15 +00:00
@computed('clientStatus')
get statusClass() {
const classMap = {
pending: 'is-pending',
running: 'is-primary',
complete: 'is-complete',
failed: 'is-error',
lost: 'is-light',
unknown: 'is-unknown',
};
2019-03-26 07:46:44 +00:00
return classMap[this.clientStatus] || 'is-dark';
}
@computed('jobVersion', 'job.version')
get isOld() {
return this.jobVersion !== this.get('job.version');
}
@computed('isOld', 'jobTaskGroup', 'allocationTaskGroup')
get taskGroup() {
if (!this.isOld) return this.jobTaskGroup;
return this.allocationTaskGroup;
}
@computed('taskGroupName', 'job.taskGroups.[]')
get jobTaskGroup() {
2017-09-19 14:47:10 +00:00
const taskGroups = this.get('job.taskGroups');
2019-03-26 07:46:44 +00:00
return taskGroups && taskGroups.findBy('name', this.taskGroupName);
}
2017-09-19 14:47:10 +00:00
@fragment('task-group', { defaultValue: null }) allocationTaskGroup;
@computed('taskGroup.drivers.[]', 'node.unhealthyDriverNames.[]')
get unhealthyDrivers() {
const taskGroupUnhealthyDrivers = this.get('taskGroup.drivers');
const nodeUnhealthyDrivers = this.get('node.unhealthyDriverNames');
if (taskGroupUnhealthyDrivers && nodeUnhealthyDrivers) {
return intersection(taskGroupUnhealthyDrivers, nodeUnhealthyDrivers);
}
return [];
}
// When per_alloc is set to true on a volume, the volumes are duplicated between active allocations.
// We differentiate them with a [#] suffix, inferred from a volume's allocation's name property.
@computed('name')
get volumeExtension() {
return this.name.substring(this.name.lastIndexOf('['));
}
@fragmentArray('task-state') states;
@fragmentArray('reschedule-event') rescheduleEvents;
@computed('rescheduleEvents.length', 'nextAllocation')
get hasRescheduleEvents() {
2019-03-26 07:46:44 +00:00
return this.get('rescheduleEvents.length') > 0 || this.nextAllocation;
}
2021-12-28 16:08:12 +00:00
@computed(
'clientStatus',
'followUpEvaluation.content',
'nextAllocation.content'
)
get hasStoppedRescheduling() {
return (
!this.get('nextAllocation.content') &&
!this.get('followUpEvaluation.content') &&
this.clientStatus === 'failed'
);
}
stop() {
return this.store.adapterFor('allocation').stop(this);
}
restart(taskName) {
return this.store.adapterFor('allocation').restart(this, taskName);
}
restartAll() {
return this.store.adapterFor('allocation').restartAll(this);
}
ls(path) {
return this.store.adapterFor('allocation').ls(this, path);
}
stat(path) {
return this.store.adapterFor('allocation').stat(this, path);
}
}