github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/ui/mirage/factories/allocation.js (about) 1 import Ember from 'ember'; 2 import moment from 'moment'; 3 import { Factory, trait } from 'ember-cli-mirage'; 4 import faker from 'nomad-ui/mirage/faker'; 5 import { provide, pickOne } from '../utils'; 6 import { generateResources } from '../common'; 7 8 const UUIDS = provide(100, faker.random.uuid.bind(faker.random)); 9 const CLIENT_STATUSES = ['pending', 'running', 'complete', 'failed', 'lost']; 10 const DESIRED_STATUSES = ['run', 'stop', 'evict']; 11 const REF_TIME = new Date(); 12 13 export default Factory.extend({ 14 id: i => (i >= 100 ? `${UUIDS[i % 100]}-${i}` : UUIDS[i]), 15 16 jobVersion: 1, 17 18 modifyIndex: () => faker.random.number({ min: 10, max: 2000 }), 19 modifyTime: () => faker.date.past(2 / 365, REF_TIME) * 1000000, 20 21 createIndex: () => faker.random.number({ min: 10, max: 2000 }), 22 createTime() { 23 return faker.date.past(2 / 365, new Date(this.modifyTime / 1000000)) * 1000000; 24 }, 25 26 namespace: null, 27 28 clientStatus() { 29 return this.forceRunningClientStatus ? 'running' : faker.helpers.randomize(CLIENT_STATUSES); 30 }, 31 32 desiredStatus: () => faker.helpers.randomize(DESIRED_STATUSES), 33 34 // When true, doesn't create any resources, state, or events 35 shallow: false, 36 37 // When true, sets the client status to running 38 forceRunningClientStatus: false, 39 40 withTaskWithPorts: trait({ 41 afterCreate(allocation, server) { 42 const taskGroup = server.db.taskGroups.findBy({ name: allocation.taskGroup }); 43 const resources = taskGroup.taskIds.map(id => 44 server.create( 45 'task-resource', 46 { 47 allocation, 48 name: server.db.tasks.find(id).name, 49 }, 50 'withReservedPorts' 51 ) 52 ); 53 54 allocation.update({ taskResourceIds: resources.mapBy('id') }); 55 }, 56 }), 57 58 withoutTaskWithPorts: trait({ 59 afterCreate(allocation, server) { 60 const taskGroup = server.db.taskGroups.findBy({ name: allocation.taskGroup }); 61 const resources = taskGroup.taskIds.map(id => 62 server.create( 63 'task-resource', 64 { 65 allocation, 66 name: server.db.tasks.find(id).name, 67 }, 68 'withoutReservedPorts' 69 ) 70 ); 71 72 allocation.update({ taskResourceIds: resources.mapBy('id') }); 73 }, 74 }), 75 76 withAllocatedResources: trait({ 77 allocatedResources: () => { 78 return { 79 Shared: generateResources({ networks: { minPorts: 2 } }), 80 }; 81 }, 82 }), 83 84 rescheduleAttempts: 0, 85 rescheduleSuccess: false, 86 87 rescheduled: trait({ 88 // Create another allocation carrying the events of this as well as the reschduleSuccess state. 89 // Pass along rescheduleAttempts after decrementing. 90 // After rescheduleAttempts hits zero, a final allocation is made with no nextAllocation and 91 // a clientStatus of failed or running, depending on rescheduleSuccess 92 afterCreate(allocation, server) { 93 const attempts = allocation.rescheduleAttempts - 1; 94 const previousEvents = 95 (allocation.rescheduleTracker && allocation.rescheduleTracker.Events) || []; 96 97 let rescheduleTime; 98 if (previousEvents.length) { 99 const lastEvent = previousEvents[previousEvents.length - 1]; 100 rescheduleTime = moment(lastEvent.RescheduleTime / 1000000).add(5, 'minutes'); 101 } else { 102 rescheduleTime = faker.date.past(2 / 365, REF_TIME); 103 } 104 105 rescheduleTime *= 1000000; 106 107 const rescheduleTracker = { 108 Events: previousEvents.concat([ 109 { 110 PrevAllocID: allocation.id, 111 PrevNodeID: null, //allocation.node.id, 112 RescheduleTime: rescheduleTime, 113 }, 114 ]), 115 }; 116 117 let nextAllocation; 118 if (attempts > 0) { 119 nextAllocation = server.create('allocation', 'rescheduled', { 120 rescheduleAttempts: Math.max(attempts, 0), 121 rescheduleSuccess: allocation.rescheduleSuccess, 122 previousAllocation: allocation.id, 123 shallow: allocation.shallow, 124 clientStatus: 'failed', 125 rescheduleTracker, 126 followupEvalId: server.create('evaluation', { 127 waitUntil: rescheduleTime, 128 }).id, 129 }); 130 } else { 131 nextAllocation = server.create('allocation', { 132 previousAllocation: allocation.id, 133 clientStatus: allocation.rescheduleSuccess ? 'running' : 'failed', 134 shallow: allocation.shallow, 135 rescheduleTracker, 136 }); 137 } 138 139 allocation.update({ nextAllocation: nextAllocation.id, clientStatus: 'failed' }); 140 }, 141 }), 142 143 preempted: trait({ 144 afterCreate(allocation, server) { 145 const preempter = server.create('allocation', { preemptedAllocations: [allocation.id] }); 146 allocation.update({ preemptedByAllocation: preempter.id }); 147 }, 148 }), 149 150 preempter: trait({ 151 afterCreate(allocation, server) { 152 const preempted = server.create('allocation', { preemptedByAllocation: allocation.id }); 153 allocation.update({ preemptedAllocations: [preempted.id] }); 154 }, 155 }), 156 157 afterCreate(allocation, server) { 158 Ember.assert( 159 '[Mirage] No jobs! make sure jobs are created before allocations', 160 server.db.jobs.length 161 ); 162 Ember.assert( 163 '[Mirage] No nodes! make sure nodes are created before allocations', 164 server.db.nodes.length 165 ); 166 167 const job = allocation.jobId ? server.db.jobs.find(allocation.jobId) : pickOne(server.db.jobs); 168 const namespace = allocation.namespace || job.namespace; 169 const node = allocation.nodeId 170 ? server.db.nodes.find(allocation.nodeId) 171 : pickOne(server.db.nodes); 172 const taskGroup = allocation.taskGroup 173 ? server.db.taskGroups.findBy({ name: allocation.taskGroup }) 174 : pickOne(server.db.taskGroups.where({ jobId: job.id })); 175 176 allocation.update({ 177 namespace, 178 jobId: job.id, 179 nodeId: node.id, 180 taskStateIds: [], 181 taskResourceIds: [], 182 taskGroup: taskGroup.name, 183 name: allocation.name || `${taskGroup.name}.[${faker.random.number(10)}]`, 184 }); 185 186 if (!allocation.shallow) { 187 const states = taskGroup.taskIds.map(id => 188 server.create('task-state', { 189 allocation, 190 name: server.db.tasks.find(id).name, 191 }) 192 ); 193 194 const resources = taskGroup.taskIds.map(id => 195 server.create('task-resource', { 196 allocation, 197 name: server.db.tasks.find(id).name, 198 }) 199 ); 200 201 allocation.update({ 202 taskStateIds: allocation.clientStatus === 'pending' ? [] : states.mapBy('id'), 203 taskResourceIds: allocation.clientStatus === 'pending' ? [] : resources.mapBy('id'), 204 }); 205 206 // Each allocation has a corresponding allocation stats running on some client. 207 // Create that record, even though it's not a relationship. 208 server.create('client-allocation-stat', { 209 id: allocation.id, 210 _taskNames: states.mapBy('name'), 211 }); 212 } 213 }, 214 });