Closed SpanishPear closed 2 years ago
It'll take a little bit to implement, but I think this can be done when #253 is (partially) implemented/released.
Basically bind to e.g. /tmp/vscode-sshfs-<random-UUID-or-timestamp>.sock
which is remotely forwarded by the extension and listens for commands. A bash alias (or even an overridden $EDITOR
variable) could then be added to perform echo "open <filepath>\n" > /tmp/...
. Haven't tested it yet, but I imagine this would be a relatively simple way of adding support for this.
The only caveat I'd add:
We're trying to migrate our users to SSH-FS away from remote-ssh, because we have thousands of users connecting to our servers, and the .vscode-server backend that remote-ssh uses is a massive CPU/RAM/pid/disk hog - trivial for single-user boxes, but a major problem for significantly-multi-user environments. (it's also hilariously insecure by default, and people can end up running other users' shells accidentally unless they drill down into the config to use sockets instead of TCP...)
Killing stuck or leftover backend processes by the hundreds, and fielding multiple tickets daily to clear out corrupted or quota-eating .vscode-server directories is also a significant chunk of our daily workflow that we really want to get away from, and if we end up going back there, I may possibly cry.
If you do implement a backend process, I beg you to focus on keeping it as lightweight and stateless as possible. I will owe you one, seriously.
If you do implement a backend process, I beg you to focus on keeping it as lightweight and stateless as possible. I will owe you one, seriously.
I wasn't really thinking about a backend process anyway, as this would require the host to have NodeJS to run the backend code. That, or me having to write and provide (built) executables for every OS, which I'm even less a fan of. My idea was just to have a simple socket (a UNIX one, to prevent having to deal with reserved ports and such) which is either port forwarded through SSH, or optionally running a background SSH terminal that creates and listens to this socket, although the latter is unlikely.
Made some progress, although actually injecting the code
alias/function in the shell is tricky. And actually creating a code
program in some .../bin
directory seems a bit icky.
Currently I'm overwriting the PROMPT_COMMAND
environment variable (for Bash) and the ENV
environment variable (for sh
) to have them load a temporary file (including in subshells) that adds the alias. Not the cleanest, and definitely not the most reliable/robust, let alone whether it supports other shells.
It's either that, going through all possible .profile
and similar files and injecting source /tmp/something
if not present yet, or having the user manually add that to their profile. and that's assuming I can write a .sh
script that all shells accept.
Besides the "how to load code
command", I'm not still entirely sure how to actually make it work:
/dev/pts/123
in an environment variable which is what code
writes to. Problem with this is that I can check whether that character device still exists, but not (easily) check whether it's the extension-owned shell.mknode
to create a unique pipe, but the problem being that I can't seemingly detect whether the pipe is still being read, without doing weird timeout stuff.nc
) in listening mode to create a proper Unix socket that outputs to the background terminal. Problem being that netcat isn't actually present on every OS as far as I know.Both issues are already quite complex on their own, so it's taking quite some time and effort to get it working consistently across multiple shells. And I've only tried (and perhaps might even only try) bash
and sh
, nothing else. I'm assuming that any script I write that's compatible with the Bourne shell (sh
) will be source
-able by all shells, and that the PROXY_COMMAND
/ENV
"hack" I'm using now is also good enough.
TL;DR: Lots of work with complex Unix/shell mechanics, but there's at least progress.
I'll probably quickly finish the current half-baked setup I have and push it to a feature branch (or publicly released but only enabled with certain flags), so you can try the code
command out yourself and give feedback or, more likely, find bugs. Then I'll continue on #252 before coming back to this.
I've pushed an initial prototype to the master branch, you can download the extension from the latest build in this list.
To activate this feature, there are two ways:
REMOTE_COMMANDS
flag to "sshfs.flags"
in your User Settings, like this:
"sshfs.flags": [
"REMOTE_COMMANDS"
],
REMOTE_COMMANDS
flag to your (JSON) config's "flags"
field, like this:
"sshfs.configs": [
{
"name": "some-config",
"host": "hostname",
"putty": true,
"flags": [
"REMOTE_COMMANDS"
]
}
],
Once that's added, every new connection will make use of the feature, so I recommend reloading the window. When you open a remote terminal through the extension, it should display Injected 'code' alias
once and whenever you create an interactive subshell.
The code
command expects a single argument, namely a relative or absolute path to a file/directory you want to open. Files will be opened in editors, while directories will be added as workspace folders.
Like I mentioned in my previous comment, the current setup isn't the most elegant or robust, your mileage might vary. Also note that the code
command only sends an instruction to the extension and immediately returns. Errors are displayed in VS Code, and the command doesn't wait for the opened editor to be closed. Can't use it for e.g. git for now.
The initial prototype is available in v1.21.0 of the extension, so you don't require to manually download and install the built .vsix
file. Nothing changed since my last comment though, e.g. it requires the REMOTE_COMMANDS
flag and might easily break.
Thanks heaps @SchoofsKelvin - this looks awesome! I'll have a play around :partying_face:
Hi @SchoofsKelvin, this seems to be working wonderfully!
That being said, I was wondering if it'd be possible for the code
alias to create a file and open it rather than throw an EntryNotFound
error if the file doesn't exist
Thanks 😄
@abiramen Can you test the latest build (68 or later) from here? Run the Extensions: Install from VSIX
command and select the .vsix
artifact file. When trying to open a file that doesn't exist, it should prompt you to create an empty file first.
Mind that it does actually create that empty file. The extension API doesn't seem to allow me to (easily) create an unsaved document for a non-existing URI. Technically I could trick VS Code into allowing this, but hacky and a bit of work.
This works great! Thanks @SchoofsKelvin 🎉
Would it be possible to add this functionality for the zsh
shell also? If not, perhaps a nudge in the right direction so I can try reverse engineer the work done on the sh
and bash
shells.
So far the profile config files haven't really helped in deciphering how this works.
I've just pushed some commits that should, if I didn't do anything wrong, support most shells. Below is the current list, which I didn't test in-depth yet, but should work for those shells and most shells based on them:
You can get the latest build from here (build 87 or later) if you want to try it out yourself. I'll release it after some more feedback/testing.
More shell support (from my previous comment) added in v1.24.0 of the extension.
Hello,
I'm trying to use this on systems where the default shell is /bin/csh, but it doesn't work. It appears that the shell type is not being detected correctly because the extension tries to use the "export" command to set things up instead of "setenv".
EDIT: I switched on logging but I don't see any errors in the SSH FS log.
example terminal output:
Connecting to eda... export: Command not found. export: Command not found. $
So, check the SHELL value...
$ echo $SHELL /bin/csh
this is actually a link to tcsh:
/bin/csh -> tcsh
Thanks
This issue would be easier to solve with debug logs, so please follow these steps:
DEBUG_SSH2
to the sshfs.flags
array in VS Code's User Settings (settings.json)
e.g. "sshfs.flags": ["DEBUG_SSH2"]
Output > SSH FS
and copy the log from there after replicating your bugDEBUG_SSH2
activates some internal logging, which is less likely to be censored)_That should log which kind of shell it actually thinks you're using. My guess is the detection goes wrong, since csh
should get detected:
https://github.com/SchoofsKelvin/vscode-sshfs/blob/2673c726c84a3f73983b344ae6c9ce73d8fb284b/src/shellConfig.ts#L82
Thanks for the response, here's the log
I've just noticed that as you suspected there is an error when detecting the shell config :
[ERROR] [createConnection(eda,config)] Error calculating ShellConfig: Error: Command 'echo :::SHELL:$SHELL:SHELL:::' failed with exit code 1: Bad : modifier in $ (S). Error: Command 'echo :::SHELL:$SHELL:SHELL:::' failed with exit code 1: Bad : modifier in $ (S).
I guess this needs to be changed by adding braces:
echo :::SHELL:${SHELL}:SHELL:::
which for csh at least should return: :::SHELL:/bin/csh:SHELL:::
UPDATE: I can confirm that changing $SHELL to ${SHELL} fixes the issue for csh and doesn't cause problems for bash/sh. I've simply updated the minified extension.js file that I already have installed to test this. Would you prefer a pull request?
Hi!
I was wondering if there's any way to open a mounted file on the commandline from my ssh-terminal (as opened by the extension)?
Thanks!