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