github.com/aminovpavel/nomad@v0.11.8/ui/app/controllers/exec.js (about)

     1  import { inject as service } from '@ember/service';
     2  import Controller from '@ember/controller';
     3  import { computed } from '@ember/object';
     4  import { alias, mapBy, sort, uniq } from '@ember/object/computed';
     5  import escapeTaskName from 'nomad-ui/utils/escape-task-name';
     6  import ExecCommandEditorXtermAdapter from 'nomad-ui/utils/classes/exec-command-editor-xterm-adapter';
     7  import ExecSocketXtermAdapter from 'nomad-ui/utils/classes/exec-socket-xterm-adapter';
     8  import localStorageProperty from 'nomad-ui/utils/properties/local-storage';
     9  
    10  import { Terminal } from 'xterm-vendor';
    11  
    12  const ANSI_UI_GRAY_400 = '\x1b[38;2;142;150;163m';
    13  const ANSI_WHITE = '\x1b[0m';
    14  
    15  export default Controller.extend({
    16    sockets: service(),
    17    system: service(),
    18    token: service(),
    19  
    20    queryParams: ['allocation'],
    21  
    22    command: localStorageProperty('nomadExecCommand', '/bin/bash'),
    23    socketOpen: false,
    24  
    25    pendingAndRunningAllocations: computed('model.allocations.@each.clientStatus', function() {
    26      return this.model.allocations.filter(
    27        allocation => allocation.clientStatus === 'pending' || allocation.clientStatus === 'running'
    28      );
    29    }),
    30  
    31    pendingAndRunningTaskGroups: mapBy('pendingAndRunningAllocations', 'taskGroup'),
    32    uniquePendingAndRunningTaskGroups: uniq('pendingAndRunningTaskGroups'),
    33  
    34    taskGroupSorting: Object.freeze(['name']),
    35    sortedTaskGroups: sort('uniquePendingAndRunningTaskGroups', 'taskGroupSorting'),
    36  
    37    init() {
    38      this._super(...arguments);
    39  
    40      this.terminal = new Terminal({ fontFamily: 'monospace', fontWeight: '400' });
    41      window.execTerminal = this.terminal; // Issue to improve: https://github.com/hashicorp/nomad/issues/7457
    42  
    43      this.terminal.write(ANSI_UI_GRAY_400);
    44      this.terminal.writeln('Select a task to start your session.');
    45    },
    46  
    47    allocations: alias('model.allocations'),
    48  
    49    taskState: computed(
    50      'allocations.[]',
    51      'allocationShortId',
    52      'allocations.@each.isActive',
    53      'taskName',
    54      'taskGroupName',
    55      'allocation',
    56      'allocation.states.@each.name',
    57      'allocation.states.@each.isRunning',
    58      function() {
    59        if (!this.allocations) {
    60          return false;
    61        }
    62  
    63        let allocation;
    64  
    65        if (this.allocationShortId) {
    66          allocation = this.allocations.findBy('shortId', this.allocationShortId);
    67        } else {
    68          allocation = this.allocations.find(allocation =>
    69            allocation.states
    70              .filterBy('isActive')
    71              .mapBy('name')
    72              .includes(this.taskName)
    73          );
    74        }
    75  
    76        if (allocation) {
    77          return allocation.states.find(state => state.name === this.taskName);
    78        }
    79      }
    80    ),
    81  
    82    actions: {
    83      setTaskProperties({ allocationShortId, taskName, taskGroupName }) {
    84        this.setProperties({
    85          allocationShortId,
    86          taskName,
    87          taskGroupName,
    88        });
    89  
    90        if (this.taskState) {
    91          this.terminal.write(ANSI_UI_GRAY_400);
    92          this.terminal.writeln('');
    93  
    94          if (!allocationShortId) {
    95            this.terminal.writeln(
    96              'Multiple instances of this task are running. The allocation below was selected by random draw.'
    97            );
    98            this.terminal.writeln('');
    99          }
   100  
   101          this.terminal.writeln('Customize your command, then hit ‘return’ to run.');
   102          this.terminal.writeln('');
   103          this.terminal.write(
   104            `$ nomad alloc exec -i -t -task ${escapeTaskName(taskName)} ${
   105              this.taskState.allocation.shortId
   106            } `
   107          );
   108  
   109          this.terminal.write(ANSI_WHITE);
   110  
   111          this.terminal.write(this.command);
   112  
   113          if (this.commandEditorAdapter) {
   114            this.commandEditorAdapter.destroy();
   115          }
   116  
   117          this.commandEditorAdapter = new ExecCommandEditorXtermAdapter(
   118            this.terminal,
   119            this.openAndConnectSocket.bind(this),
   120            this.command
   121          );
   122        }
   123      },
   124    },
   125  
   126    openAndConnectSocket(command) {
   127      if (this.taskState) {
   128        this.set('socketOpen', true);
   129        this.set('command', command);
   130        this.socket = this.sockets.getTaskStateSocket(this.taskState, command);
   131  
   132        new ExecSocketXtermAdapter(this.terminal, this.socket, this.token.secret);
   133      } else {
   134        this.terminal.writeln(`Failed to open a socket because task ${this.taskName} is not active.`);
   135      }
   136    },
   137  });