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