github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/ui/app/models/allocation.js (about) 1 import { inject as service } from '@ember/service'; 2 import { computed } from '@ember/object'; 3 import { equal, none } from '@ember/object/computed'; 4 import Model from 'ember-data/model'; 5 import attr from 'ember-data/attr'; 6 import { belongsTo, hasMany } from 'ember-data/relationships'; 7 import { fragment, fragmentArray } from 'ember-data-model-fragments/attributes'; 8 import intersection from 'lodash.intersection'; 9 import shortUUIDProperty from '../utils/properties/short-uuid'; 10 11 const STATUS_ORDER = { 12 pending: 1, 13 running: 2, 14 complete: 3, 15 failed: 4, 16 lost: 5, 17 }; 18 19 export default Model.extend({ 20 token: service(), 21 22 shortId: shortUUIDProperty('id'), 23 job: belongsTo('job'), 24 node: belongsTo('node'), 25 name: attr('string'), 26 taskGroupName: attr('string'), 27 resources: fragment('resources'), 28 allocatedResources: fragment('resources'), 29 jobVersion: attr('number'), 30 31 modifyIndex: attr('number'), 32 modifyTime: attr('date'), 33 34 createIndex: attr('number'), 35 createTime: attr('date'), 36 37 clientStatus: attr('string'), 38 desiredStatus: attr('string'), 39 statusIndex: computed('clientStatus', function() { 40 return STATUS_ORDER[this.clientStatus] || 100; 41 }), 42 43 isRunning: equal('clientStatus', 'running'), 44 isMigrating: attr('boolean'), 45 46 // An allocation model created from any allocation list response will be lacking 47 // many properties (some of which can always be null). This is an indicator that 48 // the allocation needs to be reloaded to get the complete allocation state. 49 isPartial: none('allocationTaskGroup'), 50 51 // When allocations are server-side rescheduled, a paper trail 52 // is left linking all reschedule attempts. 53 previousAllocation: belongsTo('allocation', { inverse: 'nextAllocation' }), 54 nextAllocation: belongsTo('allocation', { inverse: 'previousAllocation' }), 55 56 preemptedAllocations: hasMany('allocation', { inverse: 'preemptedByAllocation' }), 57 preemptedByAllocation: belongsTo('allocation', { inverse: 'preemptedAllocations' }), 58 wasPreempted: attr('boolean'), 59 60 followUpEvaluation: belongsTo('evaluation'), 61 62 statusClass: computed('clientStatus', function() { 63 const classMap = { 64 pending: 'is-pending', 65 running: 'is-primary', 66 complete: 'is-complete', 67 failed: 'is-error', 68 lost: 'is-light', 69 }; 70 71 return classMap[this.clientStatus] || 'is-dark'; 72 }), 73 74 isOld: computed('jobVersion', 'job.version', function() { 75 return this.jobVersion !== this.get('job.version'); 76 }), 77 78 taskGroup: computed('isOld', 'jobTaskGroup', 'allocationTaskGroup', function() { 79 if (!this.isOld) return this.jobTaskGroup; 80 return this.allocationTaskGroup; 81 }), 82 83 jobTaskGroup: computed('taskGroupName', 'job.taskGroups.[]', function() { 84 const taskGroups = this.get('job.taskGroups'); 85 return taskGroups && taskGroups.findBy('name', this.taskGroupName); 86 }), 87 88 allocationTaskGroup: fragment('task-group', { defaultValue: null }), 89 90 unhealthyDrivers: computed('taskGroup.drivers.[]', 'node.unhealthyDriverNames.[]', function() { 91 const taskGroupUnhealthyDrivers = this.get('taskGroup.drivers'); 92 const nodeUnhealthyDrivers = this.get('node.unhealthyDriverNames'); 93 94 if (taskGroupUnhealthyDrivers && nodeUnhealthyDrivers) { 95 return intersection(taskGroupUnhealthyDrivers, nodeUnhealthyDrivers); 96 } 97 98 return []; 99 }), 100 101 states: fragmentArray('task-state'), 102 rescheduleEvents: fragmentArray('reschedule-event'), 103 104 hasRescheduleEvents: computed('rescheduleEvents.length', 'nextAllocation', function() { 105 return this.get('rescheduleEvents.length') > 0 || this.nextAllocation; 106 }), 107 108 hasStoppedRescheduling: computed( 109 'nextAllocation', 110 'clientStatus', 111 'followUpEvaluation.content', 112 function() { 113 return ( 114 !this.get('nextAllocation.content') && 115 !this.get('followUpEvaluation.content') && 116 this.clientStatus === 'failed' 117 ); 118 } 119 ), 120 121 stop() { 122 return this.store.adapterFor('allocation').stop(this); 123 }, 124 125 restart(taskName) { 126 return this.store.adapterFor('allocation').restart(this, taskName); 127 }, 128 });