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  });