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