github.com/manicqin/nomad@v0.9.5/ui/app/models/allocation.js (about) 1 import { inject as service } from '@ember/service'; 2 import { computed } from '@ember/object'; 3 import { equal } 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 45 // When allocations are server-side rescheduled, a paper trail 46 // is left linking all reschedule attempts. 47 previousAllocation: belongsTo('allocation', { inverse: 'nextAllocation' }), 48 nextAllocation: belongsTo('allocation', { inverse: 'previousAllocation' }), 49 50 preemptedAllocations: hasMany('allocation', { inverse: 'preemptedByAllocation' }), 51 preemptedByAllocation: belongsTo('allocation', { inverse: 'preemptedAllocations' }), 52 wasPreempted: attr('boolean'), 53 54 followUpEvaluation: belongsTo('evaluation'), 55 56 statusClass: computed('clientStatus', function() { 57 const classMap = { 58 pending: 'is-pending', 59 running: 'is-primary', 60 complete: 'is-complete', 61 failed: 'is-error', 62 lost: 'is-light', 63 }; 64 65 return classMap[this.clientStatus] || 'is-dark'; 66 }), 67 68 taskGroup: computed('taskGroupName', 'job.taskGroups.[]', function() { 69 const taskGroups = this.get('job.taskGroups'); 70 return taskGroups && taskGroups.findBy('name', this.taskGroupName); 71 }), 72 73 unhealthyDrivers: computed('taskGroup.drivers.[]', 'node.unhealthyDriverNames.[]', function() { 74 const taskGroupUnhealthyDrivers = this.get('taskGroup.drivers'); 75 const nodeUnhealthyDrivers = this.get('node.unhealthyDriverNames'); 76 77 if (taskGroupUnhealthyDrivers && nodeUnhealthyDrivers) { 78 return intersection(taskGroupUnhealthyDrivers, nodeUnhealthyDrivers); 79 } 80 81 return []; 82 }), 83 84 states: fragmentArray('task-state'), 85 rescheduleEvents: fragmentArray('reschedule-event'), 86 87 hasRescheduleEvents: computed('rescheduleEvents.length', 'nextAllocation', function() { 88 return this.get('rescheduleEvents.length') > 0 || this.nextAllocation; 89 }), 90 91 hasStoppedRescheduling: computed( 92 'nextAllocation', 93 'clientStatus', 94 'followUpEvaluation.content', 95 function() { 96 return ( 97 !this.get('nextAllocation.content') && 98 !this.get('followUpEvaluation.content') && 99 this.clientStatus === 'failed' 100 ); 101 } 102 ), 103 104 stop() { 105 return this.store.adapterFor('allocation').stop(this); 106 }, 107 108 restart(taskName) { 109 return this.store.adapterFor('allocation').restart(this, taskName); 110 }, 111 });