Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: add exec terminal #6697

Merged
merged 154 commits into from
Mar 24, 2020
Merged
Show file tree
Hide file tree
Changes from 138 commits
Commits
Show all changes
154 commits
Select commit Hold shift + click to select a range
7256769
Add proxy that properly handles websockets
backspace Nov 13, 2019
11b0da4
Add xterm.js
backspace Nov 13, 2019
a6aed62
Add comment about proxy being preliminary
backspace Nov 13, 2019
caccb4b
Add prototype task-attached exec terminal
backspace Nov 13, 2019
3f9fcb4
Fix lint errors
backspace Nov 13, 2019
9bef4ad
Fix encoding to handle emoji 🥳
backspace Nov 14, 2019
dd4ecf9
Merge branch 'master' into f-ui/exec
backspace Jan 27, 2020
1b92691
Add preliminary exec popup sidebar
backspace Jan 27, 2020
55ef273
Add show/hide of task group task list
backspace Jan 28, 2020
dce93dd
Add preliminary styling
backspace Jan 28, 2020
a0a8f88
Change icon selector to have correct scope
backspace Jan 28, 2020
4bc5838
Correct colour for exit icon
backspace Jan 28, 2020
16160e1
Add preliminary header with job details
backspace Jan 29, 2020
43370ea
Change region/namespace to show conditionally
backspace Jan 29, 2020
922ebd9
Add styling for popup navbar
backspace Jan 29, 2020
0eaf145
Remove new-window target for documentation for now
backspace Jan 29, 2020
1710751
Add terminal with task selection message
backspace Jan 30, 2020
61c09b6
Remove integration test for now
backspace Jan 30, 2020
75c2c57
Add auto-fit for terminal
backspace Feb 3, 2020
6bd195e
Add width for exec sidebar
backspace Feb 3, 2020
0256014
Add padding around terminal element
backspace Feb 3, 2020
8747919
Change task group to be closed by default
backspace Feb 3, 2020
3ff8f49
Change task group to be opened by routing
backspace Feb 3, 2020
94e50b2
Change task items to links
backspace Feb 4, 2020
e6c469a
Add first step toward editable command output
backspace Feb 4, 2020
20b7b14
Add handling for assigning/specifying allocations
backspace Feb 5, 2020
417f317
Add foreground text colouring
backspace Feb 5, 2020
9cbf6dc
Add note about wrapping task names in faux command
backspace Feb 5, 2020
b255650
Change typeface to match design
backspace Feb 5, 2020
4a69823
Add note about sidebar allocation mismatches
backspace Feb 5, 2020
fbc4ce1
Remove obsolete test setup
backspace Feb 5, 2020
fd3d379
Add preliminary incoming socket communication
backspace Feb 5, 2020
56a7080
Add preliminary outgoing socket communication
backspace Feb 5, 2020
f7397f1
Change sent message format for readability
backspace Feb 6, 2020
14b1883
Change terminal font to monospace
backspace Feb 6, 2020
f4dd4df
Add ability to customise exec command
backspace Feb 6, 2020
2524fb6
Add guard against backspacing beyond command
backspace Feb 6, 2020
a1960d2
Add placeholder socket for Mirage context
backspace Feb 6, 2020
91a5d38
Add preliminary handling for socket closure
backspace Feb 7, 2020
183c86a
Fix handling of emoji
backspace Feb 10, 2020
6d90cab
Change allocation choice to ensure task is present
backspace Feb 10, 2020
80c4c29
Change sidebar links to maybe open in new window
backspace Feb 10, 2020
f1cdf22
Add indicator for active task
backspace Feb 11, 2020
73668c5
Move exec-specific component to subdirectory
backspace Feb 11, 2020
568a860
Extract component for task items
backspace Feb 11, 2020
80f598d
Add temporary logging of close events
backspace Feb 11, 2020
ad1f10b
Fix lint error
backspace Feb 11, 2020
07330e5
Add temporary fixed Faker seed
backspace Feb 11, 2020
71801d0
Extract ANSI colour-changing codes
backspace Feb 12, 2020
5b0ff52
Add escaping for faux CLI task names
backspace Feb 12, 2020
0ffe645
Add link to origin of escaping regular expression
backspace Feb 12, 2020
1649705
Remove superfluous comments
backspace Feb 12, 2020
844de68
Fix sidebar for multi-line task names
backspace Feb 13, 2020
f117e1c
Fix sidebar for multi-line task group names
backspace Feb 13, 2020
967b352
Add FIXME about keeping opened groups open
backspace Feb 13, 2020
66551ea
Add rejection of inactive task states
backspace Feb 13, 2020
5a86b9d
Add text colour change when switching tasks
backspace Feb 13, 2020
4c2713c
Extract class for terminal command-editing
backspace Feb 13, 2020
0f6a6fa
Change const to let
backspace Feb 14, 2020
123eaab
Add failing test for backspace wrapping
backspace Feb 14, 2020
2f900d2
Merge branch 'master' into f-ui/exec
backspace Feb 14, 2020
c87c365
Add wraparound backspacing for command-editing
backspace Feb 18, 2020
e0f2e60
Change new window icon to not shrink
backspace Feb 18, 2020
a47f06e
Extract adapter between Xterm.js and exec socket
backspace Feb 18, 2020
21e3d5a
Change sidebar to not shrink
backspace Feb 18, 2020
8d65a27
Change new window icon to always take up space
backspace Feb 19, 2020
840f2ff
Add tooltip for new window icon
backspace Feb 20, 2020
7fdf5ea
Add TTY-sizing message when socket opens
backspace Feb 21, 2020
5de6f89
Add note about other formats for incoming messages
backspace Feb 21, 2020
7e5bcee
Add handling for window resizing
backspace Mar 2, 2020
551d37a
Change more const to let
backspace Mar 3, 2020
4ef3388
Change documentation link to open in new tab
backspace Mar 3, 2020
e138e71
Change var to let
backspace Mar 3, 2020
83fef11
Fix bug with multiple socket-openings
backspace Mar 3, 2020
50a082d
Extract MockSocket class
backspace Mar 3, 2020
894c5ec
Update vertical height of terminal
backspace Mar 3, 2020
1429b52
Fix height of tree-and-terminal container
backspace Mar 3, 2020
ae3a465
Add assertion for terminal row count
backspace Mar 3, 2020
646e52c
Remove extraneous copypaste
backspace Mar 4, 2020
240d0e0
Add filter for what incoming frames are processed
backspace Mar 4, 2020
6c74c63
Update outdated comment
backspace Mar 4, 2020
34a2db3
Move public field into constructor
backspace Mar 4, 2020
b210afe
Remove unused variables
backspace Mar 4, 2020
8c90b76
Add required attribute
backspace Mar 4, 2020
2524bda
Change assertion on initial terminal size
backspace Mar 4, 2020
3d32307
Change TTY size assertion to reference terminal
backspace Mar 4, 2020
877fc04
Merge remote-tracking branch 'origin/master' into f-ui/exec
backspace Mar 4, 2020
f87ba12
Change resize integration test to dynamic values
backspace Mar 4, 2020
a7a528d
Remove resize test dimension changes
backspace Mar 4, 2020
97b4756
Add renaming of task state to match task
backspace Mar 5, 2020
479d9e7
Add temporary logging of test application errors
backspace Mar 5, 2020
2011286
Merge remote-tracking branch 'origin/master' into f-ui/exec
backspace Mar 5, 2020
17a5db5
Remove pending clientStatus allocations for now
backspace Mar 5, 2020
4c57467
Remove Faker override
backspace Mar 5, 2020
20a9f6d
Add flag to ensure no pending allocations
backspace Mar 5, 2020
7afcda2
Remove outdated comment
backspace Mar 5, 2020
f24ea68
Remove prototype implementation
backspace Mar 5, 2020
0566d3e
Remove note about Nomad logo in exec nav
backspace Mar 5, 2020
e40a904
Add note about application in background
backspace Mar 5, 2020
1e1f92f
Add note about hardcoded host for sockets
backspace Mar 5, 2020
90fd1a9
Remove note about icon difference
backspace Mar 6, 2020
846eca7
Change sentence about customising command
backspace Mar 6, 2020
90c003e
Fix wrapping for task group names
backspace Mar 9, 2020
1e75d90
Fix width/wrapping of task name element
backspace Mar 10, 2020
7295eaa
Add note about arrow keys
backspace Mar 10, 2020
c13b55c
Fix overflow for sidebar
backspace Mar 10, 2020
a0c177c
Replace custom reverse-wraparound handling
backspace Mar 10, 2020
7743dfd
Remove reverse-wraparound comment
backspace Mar 11, 2020
b7109f8
Add missing word
backspace Mar 11, 2020
82611c9
Add preliminary button to open exec session
backspace Mar 11, 2020
31de6d6
Change exec URL-generation to use router service
backspace Mar 11, 2020
e79c191
Add exec button to allocation title
backspace Mar 11, 2020
a448fcf
Fix border colour of exec button
backspace Mar 11, 2020
03d9a3b
Remove URL options from no-allocation URL
backspace Mar 18, 2020
4d429d7
Add skipped tests about inactive sidebar items
backspace Mar 19, 2020
1eb598b
Add exec button for task group header
backspace Mar 19, 2020
d14ec81
Add exec button for task detail header
backspace Mar 19, 2020
309f6c5
Remove unused variable
backspace Mar 19, 2020
795db54
Change socket URL-construction to be parameterised
backspace Mar 19, 2020
d4f8672
Convert to onData so paste works
backspace Mar 20, 2020
4d05dbe
Add handling for non-data stdout messages
backspace Mar 20, 2020
eda4bc0
Remove task groups on non-running allocations
backspace Mar 20, 2020
9a890d9
Add sidebar filtering to remove inactive tasks
backspace Mar 23, 2020
41273f5
Remove verified FIXME comment
backspace Mar 23, 2020
fbc915b
Extract exec URL generator
backspace Mar 24, 2020
a5a7629
Add query parameters to generated exec URLs
backspace Mar 24, 2020
1c5f8fc
Add more whitespace for consistency
backspace Mar 24, 2020
0010213
Remove allocation exec button when not running
backspace Mar 24, 2020
259b168
Remove outdated FIXME
backspace Mar 24, 2020
3805d4e
Remove FIXMEs and accept pseudo two-step-button
backspace Mar 24, 2020
39d8c09
Fix appearance of short id tag on its own line
backspace Mar 24, 2020
4240004
Extract utility to open exec windows
backspace Mar 24, 2020
c38397e
Remove outdated FIXME
backspace Mar 24, 2020
53a4c81
Remove debugging error logging
backspace Mar 24, 2020
4fb8c2b
Replace FIXMEs with issue link
backspace Mar 24, 2020
bc5615c
Remove outdated FIXMEs
backspace Mar 24, 2020
073aa25
Remove logging of socket close events
backspace Mar 24, 2020
d60076f
Remove outdated comment
backspace Mar 24, 2020
41a8046
Remove unused variable
backspace Mar 24, 2020
e1d5918
Remove duplication of exec session command
backspace Mar 24, 2020
7c486fa
Add link to issue for remembering command changes
backspace Mar 24, 2020
9e8b5da
Remove superfluous CSS comments
backspace Mar 24, 2020
53f2972
Remove extraneous whitespace
backspace Mar 24, 2020
f98619d
Replace TODO with issue link
backspace Mar 24, 2020
754df0a
Remove mock server comments
backspace Mar 24, 2020
14b59af
Add explanation of key event simulation
backspace Mar 24, 2020
c39c801
Change scrollbars to not be visible by default
backspace Mar 24, 2020
984195b
Replace custom resize-handling with mixin
backspace Mar 24, 2020
056f1f6
Remove unneeded data-fetching
backspace Mar 24, 2020
36ad190
Change component to be multi-line for readability
backspace Mar 24, 2020
a0335af
Remove unused import
backspace Mar 24, 2020
4744ddf
Extract xterm backspacing string for clarity
backspace Mar 24, 2020
8a989c3
Replace console SVG with svgo-processed version
backspace Mar 24, 2020
415c982
Change name of SVG circle for active task
backspace Mar 24, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions ui/.ember-cli
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@

Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"disableAnalytics": false,
"proxy": "http://127.0.0.1:4646"
"disableAnalytics": false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this to prevent the errors and socket pool saturation when nomad isn't running in the background? I have also ran into that, but I dunno if I'm ready to remove the proxy from here.

Thoughts on this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eep sorry, I meant to explain this. Just as I was starting to prototype this, I found that I was completely unable to connect to a websocket through that proxy because the Origin didn’t match and the request was rejected by the API. The Javascript socket interface doesn’t give you any control over that for security reasons, so I switched to the technique described here because it gives you fine-grained control. The crux for this feature is this section where the origin gets rewritten in the proxy outside the browser. It’s a shame to lose this simplicity but it seems unavoidable :////////

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow. TIL. Definitely a shame when things don't just work, but given the amount of oddities in our use of HTTP, I'm surprised the default proxy even got us this far.

}
31 changes: 31 additions & 0 deletions ui/app/components/exec-terminal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Component from '@ember/component';
import { FitAddon } from 'xterm-addon-fit';
import $ from 'jquery';

export default Component.extend({
classNames: ['terminal-container'],

didInsertElement() {
let fitAddon = new FitAddon();
this.fitAddon = fitAddon;
this.terminal.loadAddon(fitAddon);

this.terminal.open(this.element.querySelector('.terminal'));

fitAddon.fit();

this._windowResizeHandler = this.windowResizeHandler.bind(this);
$(window).on('resize', this._windowResizeHandler);
},

willDestroyElement() {
$(window).off('resize', this._windowResizeHandler);
},
backspace marked this conversation as resolved.
Show resolved Hide resolved

windowResizeHandler(e) {
this.fitAddon.fit();
if (this.terminal.resized) {
this.terminal.resized(e);
}
},
});
36 changes: 36 additions & 0 deletions ui/app/components/exec/open-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import generateExecUrl from 'nomad-ui/utils/generate-exec-url';
import openExecUrl from 'nomad-ui/utils/open-exec-url';

export default Component.extend({
tagName: '',

router: service(),

actions: {
open() {
openExecUrl(this.generateUrl());
},
},

generateUrl() {
let urlSegments = {
job: this.job.get('name'),
};

if (this.taskGroup) {
urlSegments.taskGroup = this.taskGroup.get('name');
}

if (this.task) {
urlSegments.task = this.task.get('name');
}

if (this.allocation) {
urlSegments.allocation = this.allocation.get('shortId');
}

return generateExecUrl(this.router, urlSegments);
},
});
5 changes: 5 additions & 0 deletions ui/app/components/exec/task-contents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Component from '@ember/component';

export default Component.extend({
tagName: '',
});
66 changes: 66 additions & 0 deletions ui/app/components/exec/task-group-parent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { or } from '@ember/object/computed';
import generateExecUrl from 'nomad-ui/utils/generate-exec-url';
import openExecUrl from 'nomad-ui/utils/open-exec-url';

export default Component.extend({
router: service(),

isOpen: or('clickedOpen', 'currentRouteIsThisTaskGroup'),

currentRouteIsThisTaskGroup: computed('router.currentRoute', function() {
const route = this.router.currentRoute;

if (route.name.includes('task-group')) {
const taskGroupRoute = route.parent;
const execRoute = taskGroupRoute.parent;

return (
execRoute.params.job_name === this.taskGroup.job.name &&
taskGroupRoute.params.task_group_name === this.taskGroup.name
);
} else {
return false;
}
}),

tasksWithRunningStates: computed('taskGroup', function() {
const activeStateTaskNames = this.taskGroup.allocations.reduce(
(activeStateTaskNames, allocation) => {
activeStateTaskNames = activeStateTaskNames.concat(
allocation.states
.filter(
taskState =>
taskState.isActive && taskState.task.taskGroup.name === this.taskGroup.name
)
.mapBy('name')
);

return activeStateTaskNames;
},
[]
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean now about how hairy this traversal gets.

It doesn't make it any better, and in fact I think this is technically (but insignificant at this scale), but this approach with more method chaining might be more readable?

const activeStateTaskNames = this.taskGroup.allocations
  .mapBy('states')
  .reduce((allStates, states) => allStates.concat(states), [])
  .filterBy('isActive')
  .filter(taskState => taskState.task.taskGroup.name === this.taskGroup.name)
  .mapBy('name');

Copy link
Contributor Author

@backspace backspace Mar 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I conceptually like reduce but I agree that this is Too Much. I tried replacing with your suggestion and found it was rejecting everything, I don’t understand it:

this.taskGroup.allocations
  .mapBy('states')
  .reduce((allStates, states) => allStates.concat(states), [])
  .mapBy('name')

// ["states", "states", "states", "states", "states", "states"]

this.taskGroup.allocations
  .mapBy('states')
  .reduce((allStates, states) => allStates.concat(states), [])
  .filterBy('isActive')

// [undefined, undefined, undefined, undefined, undefined, undefined]

I don’t know what’s different about it but the collected and flattened objects don’t seem like the true task states…? I would like to do something like what you suggested though, so I opened this issue to help remember, thanks.


return this.taskGroup.tasks.filter(task => activeStateTaskNames.includes(task.name));
}),

clickedOpen: false,

actions: {
toggleOpen() {
this.toggleProperty('clickedOpen');
},

openInNewWindow(job, taskGroup, task) {
let url = generateExecUrl(this.router, {
job: job.name,
taskGroup: taskGroup.name,
task: task.name,
});

openExecUrl(url);
},
},
});
81 changes: 81 additions & 0 deletions ui/app/controllers/exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { inject as service } from '@ember/service';
import Controller from '@ember/controller';
import { filterBy, mapBy, 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 { Terminal } from 'xterm-vendor';

const ANSI_UI_GRAY_400 = '\x1b[38;2;142;150;163m';
const ANSI_WHITE = '\x1b[0m';

export default Controller.extend({
sockets: service(),
system: service(),

queryParams: ['allocation'],

command: '/bin/bash',
socketOpen: false,
taskState: null,

runningAllocations: filterBy('model.allocations', 'isRunning'),
runningTaskGroups: mapBy('runningAllocations', 'taskGroup'),
uniqueRunningTaskGroups: uniq('runningTaskGroups'),

init() {
this._super(...arguments);

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.');
},

actions: {
setTaskState({ allocationSpecified, taskState }) {
this.set('taskState', taskState);

this.terminal.write(ANSI_UI_GRAY_400);
this.terminal.writeln('');

if (!allocationSpecified) {
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.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not super important but return is one of those OS specific languages at this point. Not sure what the best way tot distinguish enter vs. return or if it's even important enough to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered about it and decided to follow what the design had but I don’t love the lack of general term 😐

this.terminal.writeln('');
this.terminal.write(
`$ nomad alloc exec -i -t -task ${escapeTaskName(taskState.name)} ${
taskState.allocation.shortId
} `
);

this.terminal.write(ANSI_WHITE);

this.terminal.write('/bin/bash');

if (this.commandEditorAdapter) {
this.commandEditorAdapter.destroy();
}

this.commandEditorAdapter = new ExecCommandEditorXtermAdapter(
this.terminal,
this.openAndConnectSocket.bind(this),
'/bin/bash'
);
},
},

openAndConnectSocket(command) {
this.set('socketOpen', true);
this.socket = this.sockets.getTaskStateSocket(this.taskState, command);

new ExecSocketXtermAdapter(this.terminal, this.socket);
},
});
6 changes: 6 additions & 0 deletions ui/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ const Router = EmberRouter.extend({
});

Router.map(function() {
this.route('exec', { path: '/exec/:job_name' }, function() {
this.route('task-group', { path: '/:task_group_name' }, function() {
this.route('task', { path: '/:task_name' });
});
});

this.route('jobs', function() {
this.route('run');
this.route('job', { path: '/:job_name' }, function() {
Expand Down
27 changes: 27 additions & 0 deletions ui/app/routes/exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
import RSVP from 'rsvp';
import notifyError from 'nomad-ui/utils/notify-error';

// copied from jobs/job, issue to improve: https://github.com/hashicorp/nomad/issues/7458

export default Route.extend({
store: service(),
token: service(),

serialize(model) {
return { job_name: model.get('plainId') };
},

model(params, transition) {
const namespace = transition.to.queryParams.namespace || this.get('system.activeNamespace.id');
const name = params.job_name;
const fullId = JSON.stringify([name, namespace || 'default']);
return this.store
.findRecord('job', fullId, { reload: true })
.then(job => {
return RSVP.all([job.get('allocations'), job.get('evaluations')]).then(() => job);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are evaluations used for exec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hah they indeed are not, the perils of copypaste! I’ve removed it, thank you.

})
.catch(notifyError(this));
},
});
39 changes: 39 additions & 0 deletions ui/app/routes/exec/task-group/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';

export default Route.extend({
store: service(),

model({ task_name }) {
const allocationQueryParam = this.paramsFor('exec').allocation;

return this.modelFor('exec').allocations.then(allocations => {
let allocation;

if (allocationQueryParam) {
allocation = allocations.findBy('shortId', allocationQueryParam);
} else {
allocation = allocations.find(allocation =>
allocation.states
.filterBy('isActive')
.mapBy('name')
.includes(task_name)
);
}

return {
allocation,
allocationSpecified: allocationQueryParam ? true : false,
taskState: allocation.states.find(state => state.name === task_name),
};
});
},

afterModel(model) {
this.controllerFor('exec').send('setTaskState', model);
},

setupController(controller, { allocation, taskState }) {
controller.setProperties({ allocation, taskState });
},
});
36 changes: 36 additions & 0 deletions ui/app/services/sockets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Service from '@ember/service';
import config from 'nomad-ui/config/environment';
import { getOwner } from '@ember/application';

export default Service.extend({
getTaskStateSocket(taskState, command) {
const mirageEnabled =
config['ember-cli-mirage'] && config['ember-cli-mirage'].enabled !== false;

if (mirageEnabled) {
return new Object({
messageDisplayed: false,

send(e) {
if (!this.messageDisplayed) {
this.messageDisplayed = true;
this.onmessage({ data: `{"stdout":{"data":"${btoa('unsupported in Mirage\n\r')}"}}` });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really nice touch. I'm sure this will save someone in the future some time.

} else {
this.onmessage({ data: e.replace('stdin', 'stdout') });
}
},
});
} else {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const applicationAdapter = getOwner(this).lookup('adapter:application');
const prefix = `${applicationAdapter.host ||
window.location.host}/${applicationAdapter.urlPrefix()}`;

return new WebSocket(
`${protocol}//${prefix}/client/allocation/${taskState.allocation.id}` +
`/exec?task=${taskState.name}&tty=true` +
`&command=${encodeURIComponent(`["${command}"]`)}`
);
}
},
});
1 change: 1 addition & 0 deletions ui/app/styles/components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@import './components/ember-power-select';
@import './components/empty-message';
@import './components/error-container';
@import './components/exec';
@import './components/fs-explorer';
@import './components/gutter';
@import './components/gutter-toggle';
Expand Down
Loading