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