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

136 lines
4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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(
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 {
allocation = this.allocations.find(allocation =>
allocation.states
.filterBy('isActive')
.mapBy('name')
.includes(this.taskName)
);
}
if (allocation) {
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.`);
}
}
}