github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/ui/mirage/factories/allocation.js (about)

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