open-nomad/ui/app/controllers/exec.js

133 lines
4 KiB
JavaScript
Raw Normal View History

import { inject as service } from '@ember/service';
import Controller from '@ember/controller';
import { action, computed } from '@ember/object';
import { alias, mapBy, sort, uniq } from '@ember/object/computed';
import escapeTaskName from 'nomad-ui/utils/escape-task-name';
import ExecCommandEditorXtermAdapter from 'nomad-ui/utils/classes/exec-command-editor-xterm-adapter';
import ExecSocketXtermAdapter from 'nomad-ui/utils/classes/exec-socket-xterm-adapter';
import localStorageProperty from 'nomad-ui/utils/properties/local-storage';
import classic from 'ember-classic-decorator';
const ANSI_UI_GRAY_400 = '\x1b[38;2;142;150;163m';
const ANSI_WHITE = '\x1b[0m';
@classic
export default class ExecController extends Controller {
@service sockets;
@service system;
@service token;
queryParams = ['allocation'];
@localStorageProperty('nomadExecCommand', '/bin/bash') command;
socketOpen = false;
@computed('model.allocations.@each.clientStatus')
get pendingAndRunningAllocations() {
return this.model.allocations.filter(
2021-12-28 14:45:20 +00:00
(allocation) => allocation.clientStatus === 'pending' || allocation.clientStatus === 'running'
);
}
@mapBy('pendingAndRunningAllocations', 'taskGroup') pendingAndRunningTaskGroups;
@uniq('pendingAndRunningTaskGroups') uniquePendingAndRunningTaskGroups;
taskGroupSorting = ['name'];
@sort('uniquePendingAndRunningTaskGroups', 'taskGroupSorting') sortedTaskGroups;
setUpTerminal(Terminal) {
this.terminal = new Terminal({ fontFamily: 'monospace', fontWeight: '400' });
window.execTerminal = this.terminal; // Issue to improve: https://github.com/hashicorp/nomad/issues/7457
this.terminal.write(ANSI_UI_GRAY_400);
this.terminal.writeln('Select a task to start your session.');
}
@alias('model.allocations') allocations;
@computed(
'allocations.{[],@each.isActive}',
'allocationShortId',
'taskName',
'taskGroupName',
'allocation',
'allocation.states.@each.{name,isRunning}'
)
get taskState() {
if (!this.allocations) {
return false;
}
let allocation;
if (this.allocationShortId) {
allocation = this.allocations.findBy('shortId', this.allocationShortId);
} else {
2021-12-28 14:45:20 +00:00
allocation = this.allocations.find((allocation) =>
allocation.states.filterBy('isActive').mapBy('name').includes(this.taskName)
);
}
if (allocation) {
2021-12-28 14:45:20 +00:00
return allocation.states.find((state) => state.name === this.taskName);
}
return undefined;
}
@action
setTaskProperties({ allocationShortId, taskName, taskGroupName }) {
this.setProperties({
allocationShortId,
taskName,
taskGroupName,
});
if (this.taskState) {
this.terminal.write(ANSI_UI_GRAY_400);
this.terminal.writeln('');
if (!allocationShortId) {
this.terminal.writeln(
'Multiple instances of this task are running. The allocation below was selected by random draw.'
);
this.terminal.writeln('');
}
this.terminal.writeln('Customize your command, then hit return to run.');
this.terminal.writeln('');
this.terminal.write(
`$ nomad alloc exec -i -t -task ${escapeTaskName(taskName)} ${
this.taskState.allocation.shortId
} `
);
this.terminal.write(ANSI_WHITE);
this.terminal.write(this.command);
if (this.commandEditorAdapter) {
this.commandEditorAdapter.destroy();
}
this.commandEditorAdapter = new ExecCommandEditorXtermAdapter(
this.terminal,
this.openAndConnectSocket.bind(this),
this.command
);
}
}
openAndConnectSocket(command) {
if (this.taskState) {
this.set('socketOpen', true);
this.set('command', command);
this.socket = this.sockets.getTaskStateSocket(this.taskState, command);
new ExecSocketXtermAdapter(this.terminal, this.socket, this.token.secret);
} else {
this.terminal.writeln(`Failed to open a socket because task ${this.taskName} is not active.`);
}
}
}