2023-04-10 15:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Copyright (c) HashiCorp, Inc.
|
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
*/
|
|
|
|
|
|
2020-03-24 23:22:16 +00:00
|
|
|
|
import { inject as service } from '@ember/service';
|
|
|
|
|
import Controller from '@ember/controller';
|
2020-06-11 21:23:00 +00:00
|
|
|
|
import { action, computed } from '@ember/object';
|
2020-04-06 18:52:42 +00:00
|
|
|
|
import { alias, mapBy, sort, uniq } from '@ember/object/computed';
|
2020-03-24 23:22:16 +00:00
|
|
|
|
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';
|
2020-04-01 13:08:42 +00:00
|
|
|
|
import localStorageProperty from 'nomad-ui/utils/properties/local-storage';
|
2020-06-11 21:23:00 +00:00
|
|
|
|
import classic from 'ember-classic-decorator';
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
|
|
|
|
const ANSI_UI_GRAY_400 = '\x1b[38;2;142;150;163m';
|
|
|
|
|
const ANSI_WHITE = '\x1b[0m';
|
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
@classic
|
|
|
|
|
export default class ExecController extends Controller {
|
|
|
|
|
@service sockets;
|
|
|
|
|
@service system;
|
|
|
|
|
@service token;
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2022-12-02 20:38:01 +00:00
|
|
|
|
queryParams = ['allocation', 'namespace'];
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
@localStorageProperty('nomadExecCommand', '/bin/bash') command;
|
|
|
|
|
socketOpen = false;
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
@computed('model.allocations.@each.clientStatus')
|
|
|
|
|
get pendingAndRunningAllocations() {
|
2020-04-06 18:52:42 +00:00
|
|
|
|
return this.model.allocations.filter(
|
2021-12-28 16:08:12 +00:00
|
|
|
|
(allocation) =>
|
|
|
|
|
allocation.clientStatus === 'pending' ||
|
|
|
|
|
allocation.clientStatus === 'running'
|
2020-04-06 18:52:42 +00:00
|
|
|
|
);
|
2020-06-11 21:23:00 +00:00
|
|
|
|
}
|
2020-04-06 18:52:42 +00:00
|
|
|
|
|
2021-12-28 16:08:12 +00:00
|
|
|
|
@mapBy('pendingAndRunningAllocations', 'taskGroup')
|
|
|
|
|
pendingAndRunningTaskGroups;
|
2020-06-11 21:23:00 +00:00
|
|
|
|
@uniq('pendingAndRunningTaskGroups') uniquePendingAndRunningTaskGroups;
|
2020-04-06 18:52:42 +00:00
|
|
|
|
|
2020-06-12 20:48:52 +00:00
|
|
|
|
taskGroupSorting = ['name'];
|
2021-12-28 16:08:12 +00:00
|
|
|
|
@sort('uniquePendingAndRunningTaskGroups', 'taskGroupSorting')
|
|
|
|
|
sortedTaskGroups;
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-05-26 14:56:25 +00:00
|
|
|
|
setUpTerminal(Terminal) {
|
2021-12-28 16:08:12 +00:00
|
|
|
|
this.terminal = new Terminal({
|
|
|
|
|
fontFamily: 'monospace',
|
|
|
|
|
fontWeight: '400',
|
|
|
|
|
});
|
2020-03-24 23:22:16 +00:00
|
|
|
|
window.execTerminal = this.terminal; // Issue to improve: https://github.com/hashicorp/nomad/issues/7457
|
|
|
|
|
|
|
|
|
|
this.terminal.write(ANSI_UI_GRAY_400);
|
2022-09-02 19:20:45 +00:00
|
|
|
|
|
|
|
|
|
if (this.sortedTaskGroups.length > 0) {
|
|
|
|
|
this.terminal.writeln('Select a task to start your session.');
|
|
|
|
|
} else {
|
|
|
|
|
this.terminal.writeln(`There are no tasks running for this job.`);
|
|
|
|
|
}
|
2020-06-11 21:23:00 +00:00
|
|
|
|
}
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
@alias('model.allocations') allocations;
|
2020-04-06 18:52:42 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
@computed(
|
2020-06-09 21:03:28 +00:00
|
|
|
|
'allocations.{[],@each.isActive}',
|
2020-04-06 18:52:42 +00:00
|
|
|
|
'allocationShortId',
|
|
|
|
|
'taskName',
|
|
|
|
|
'taskGroupName',
|
|
|
|
|
'allocation',
|
2020-06-11 21:23:00 +00:00
|
|
|
|
'allocation.states.@each.{name,isRunning}'
|
|
|
|
|
)
|
|
|
|
|
get taskState() {
|
|
|
|
|
if (!this.allocations) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-04-06 18:52:42 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
let allocation;
|
2020-04-06 18:52:42 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
if (this.allocationShortId) {
|
|
|
|
|
allocation = this.allocations.findBy('shortId', this.allocationShortId);
|
|
|
|
|
} else {
|
2021-12-28 14:45:20 +00:00
|
|
|
|
allocation = this.allocations.find((allocation) =>
|
2021-12-28 16:08:12 +00:00
|
|
|
|
allocation.states
|
|
|
|
|
.filterBy('isActive')
|
|
|
|
|
.mapBy('name')
|
|
|
|
|
.includes(this.taskName)
|
2020-06-11 21:23:00 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
2020-06-09 21:03:28 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
if (allocation) {
|
2021-12-28 14:45:20 +00:00
|
|
|
|
return allocation.states.find((state) => state.name === this.taskName);
|
2020-04-06 18:52:42 +00:00
|
|
|
|
}
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
return undefined;
|
|
|
|
|
}
|
2020-04-06 19:08:22 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
@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.'
|
2020-04-06 19:08:22 +00:00
|
|
|
|
);
|
2020-06-11 21:23:00 +00:00
|
|
|
|
this.terminal.writeln('');
|
|
|
|
|
}
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2021-12-28 16:08:12 +00:00
|
|
|
|
this.terminal.writeln(
|
|
|
|
|
'Customize your command, then hit ‘return’ to run.'
|
|
|
|
|
);
|
2020-06-11 21:23:00 +00:00
|
|
|
|
this.terminal.writeln('');
|
|
|
|
|
this.terminal.write(
|
|
|
|
|
`$ nomad alloc exec -i -t -task ${escapeTaskName(taskName)} ${
|
|
|
|
|
this.taskState.allocation.shortId
|
|
|
|
|
} `
|
|
|
|
|
);
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
this.terminal.write(ANSI_WHITE);
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
this.terminal.write(this.command);
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
2020-06-11 21:23:00 +00:00
|
|
|
|
if (this.commandEditorAdapter) {
|
|
|
|
|
this.commandEditorAdapter.destroy();
|
2020-03-24 23:22:16 +00:00
|
|
|
|
}
|
2020-06-11 21:23:00 +00:00
|
|
|
|
|
|
|
|
|
this.commandEditorAdapter = new ExecCommandEditorXtermAdapter(
|
|
|
|
|
this.terminal,
|
|
|
|
|
this.openAndConnectSocket.bind(this),
|
|
|
|
|
this.command
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-24 23:22:16 +00:00
|
|
|
|
|
|
|
|
|
openAndConnectSocket(command) {
|
2020-04-06 19:08:22 +00:00
|
|
|
|
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 {
|
2021-12-28 16:08:12 +00:00
|
|
|
|
this.terminal.writeln(
|
|
|
|
|
`Failed to open a socket because task ${this.taskName} is not active.`
|
|
|
|
|
);
|
2020-04-06 19:08:22 +00:00
|
|
|
|
}
|
2020-06-11 21:23:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|