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

Investigate into code sharing opportunities with remote SSH #6137

Closed
chrmarti opened this issue Jan 6, 2022 · 11 comments
Closed

Investigate into code sharing opportunities with remote SSH #6137

chrmarti opened this issue Jan 6, 2022 · 11 comments
Assignees
Labels
containers Issue in vscode-remote containers plan-item A plan item
Milestone

Comments

@chrmarti
Copy link
Contributor

chrmarti commented Jan 6, 2022

@roblourens @tanhakabir I have collected a few notes from a Remote-Containers perspective. Feel free to add your own. A first conclusion is that it would be interesting to understand if Remote-Containers can reuse the connection from Remote-SSH's local server. I also see a lot of in-depth knowledge about OpenSSH and its features, maybe there is something Remote-Containers would benefit from too.

Remote-SSH knowledge in Remote-Containers:

  • Remote-Containers knows how to parse and create the Remote-SSH remote workspace URI:
    • "Reopen in Container" when connected with Remote-SSH transfers the SSH connection information to the Remote-Containers remote workspace URI and reopens the window with that.
    • "Reopen in SSH" when connected with Remote-Containers transfers the SSH connection information back to the Remote-SSH remote workspace URI and reopens the window with that.
  • Remote-Containers supported settings:
    • remote.SSH.path
    • remote.SSH.configFile

SSH knowledge in Remote-Containers:

  • How to start an SSH session using the ssh CLI with the connection information originating from the Remote-SSH URI.

Notes from looking at the Remote-SSH code:

  • Remote-SSH uses scripts to install the VS Code Server and the scripts run entirely on the SSH server. Remote-Containers runs shell snippets and individual commands on the SSH server with the main logic in TypeScript running on the local machine in the extension. (To reduce the impact of connection latency some of the TypeScript code could run on the SSH server. There already is the generic "Exec Server" written in TypeScript running on the SSH server.)
  • Both use SSH_ASKPASS. (Inspired by Remote-SSH at some earlier point in time.)
  • Remote-Containers always downloads the server locally.
  • Remote-Containers is currently missing support for OSX and Windows as the SSH server platform.
  • Remote-Containers has no local server to keep the connection across window reloads.
    • How does a reloading window make use of the existing connection?
@chrmarti chrmarti added containers Issue in vscode-remote containers plan-item A plan item labels Jan 6, 2022
@chrmarti chrmarti added this to the January 2022 milestone Jan 6, 2022
@hholst80
Copy link

hholst80 commented Jan 7, 2022

Just for my understanding, this is to add the possibility to make a remote container environment be Remote-ssh aware and nothing else?

@chrmarti
Copy link
Contributor Author

chrmarti commented Jan 7, 2022

We added support to Remote-Containers to connect to an SSH server and with this task we want to better understand if and what parts of the code could be shared between Remote-SSH and Remote-Containers extensions.

@tanhakabir
Copy link

How does a reloading window make use of the existing connection?

We have a server connection process running with a timeout to kill itself. Every active window every so often pings things process to extend its timeout and stay alive. When a new window is reloaded to connect to a remote host it looks at the current set of processes running and sees if its remote host and VS Code version matches on of the existing connections to use that connection instead.

@tanhakabir
Copy link

@chrmarti To help make more overlap between the SSH connections in Containers and SSH. What if we made SSH an extension dependency of Containers and have the SSH extension handle doing the SSH connection? We could expose an API for the Containers extension.

That way all the connectivity remains the same for all SSH experiences in VS Code?

@roblourens
Copy link
Member

It would make sense to me to just share the Remote-SSH resolver with the Containers extension. Is there any reason to duplicate that logic in the Containers extension? Here are some things that we can help with

  • Get a guarantee that if you can connect to a remote with Remote-SSH, you can also connect to a container over SSH
  • Support for mac and windows remotes already implemented
  • SSH has two connection modes, the "local server" and terminal-based. The terminal mode mainly has still stuck around because it works around issues with ssh on windows. There is one bug on the client side which most users should have the fix for at this point, if they install updates. There is another bug on the server side and I don't know how many users will have that fix
  • When the "local server" mode is active, the connection can be shared between windows and across reloads so the user doesn't have to reenter their password
  • There are many other switches and tweaks that will make things work better

One way to share this functionality would be to basically expose our whole resolver as extension API.

Remote-Containers always downloads the server locally.

Does that mean it is always copied over via scp?

@roblourens
Copy link
Member

@chrmarti I am not following how port forwarding works with ssh in remote-containers. We have two methods

  1. start the server, find the port it listens on
  2. start a new ssh process with -L to forward that port

or with dynamic port forwarding, the default

  1. start ssh with the -D flag to enable dynamic forwarding via socks proxy

It seems like you aren't using either of these and are doing something with your own node server but I don't understand how it works if ssh isn't involved, can you explain?

@chrmarti
Copy link
Contributor Author

@chrmarti I am not following how port forwarding works with ssh in remote-containers. We have two methods
[...]
It seems like you aren't using either of these and are doing something with your own node server but I don't understand how it works if ssh isn't involved, can you explain?

I'm using a single ssh connection to:

  • First check if we can use node (and node-pty) from an existing VS Code Server install from Remote-SSH to run the Exec Server.
  • If not, I send over node (and node-pty). (This is using a detail of dd inside the running /bin/sh to avoid the need for an additional connection. I had that from earlier investigations into performance improvements.)
  • Check if the current version of the Exec Server is there or copy it over.
  • Start the Exec Server and reuse the existing connection to talk to it over stdio. This is using a RPC/streaming library (mux-rpc) to have several channels inside the same connection.
  • Basically repeat similar steps for the container, including the port forwarding to connect to the VS Code Server inside the container.

This approach avoids much of the ssh details by using only a basic ssh connection. A lot of the code already existed either for setting up or connecting to the container or from using WSL as a simple indirection.

It would make sense to me to just share the Remote-SSH resolver with the Containers extension. Is there any reason to duplicate that logic in the Containers extension? Here are some things that we can help with

  • Get a guarantee that if you can connect to a remote with Remote-SSH, you can also connect to a container over SSH
  • Support for mac and windows remotes already implemented

I also want to look into reusing the slightly different approach of Remote-Containers with Windows (it's very close to working with Mac), but reusing Remote-SSH's local server might still make sense, also if I get that working.

  • SSH has two connection modes, the "local server" and terminal-based. The terminal mode mainly has still stuck around because it works around issues with ssh on windows. There is one bug on the client side which most users should have the fix for at this point, if they install updates. There is another bug on the server side and I don't know how many users will have that fix
  • When the "local server" mode is active, the connection can be shared between windows and across reloads so the user doesn't have to reenter their password
  • There are many other switches and tweaks that will make things work better

One way to share this functionality would be to basically expose our whole resolver as extension API.

Reusing the local server would make a lot of sense. Does that avoid the need for entering the password after a window reload?

Remote-Containers always downloads the server locally.

Does that mean it is always copied over via scp?

It sends the bits through the single ssh connection (see above, no scp involved). This is also a bit for historical reasons (made the most sense for containers) and I can look into downloading remotely if that makes sense in the future.

@chrmarti To help make more overlap between the SSH connections in Containers and SSH. What if we made SSH an extension dependency of Containers and have the SSH extension handle doing the SSH connection? We could expose an API for the Containers extension.

I would like to avoid an explicit dependency in the package.json since Remote-SSH isn't needed unless we are using an SSH server. Remote-Containers could check at runtime if Remote-SSH is installed and use its API (if that is possible for a resolver before resolving has finished) or the local server directly.

@chrmarti
Copy link
Contributor Author

Someone mentioned Git credential forwarding does not work in Remote-SSH (and I didn't see it in code, although I would expect VS Code's Git-Askpass support to kick in too), maybe something that can be reused from Remote-Containers: #6168

@tanhakabir
Copy link

tanhakabir commented Jan 20, 2022

Does that avoid the need for entering the password after a window reload?

This would avoid the need to enter password on reload yes.

I would like to avoid an explicit dependency in the package.json since Remote-SSH isn't needed unless we are using an SSH server. Remote-Containers could check at runtime if Remote-SSH is installed and use its API (if that is possible for a resolver before resolving has finished) or the local server directly.

This makes sense as well. The details of the local server are saved on your machine. (How we find already running local server on new windows https://github.com/microsoft/vscode-remote-ssh/blob/51d2a9264fd300a26ad7666c61785d594f3bb861/open-ssh-remote/src/local-server.ts#L91). We could expose a bit more an API to work with Containers?

@chrmarti
Copy link
Contributor Author

That would be great. I just checked if Remote-Containers can get at the object returned from Remote-SSH's activate function when the Remote-Containers resolver is still running and the extension object's exports property always returns undefined. @alexdima Is it possible for a resolver to use another extension's API object?

@chrmarti
Copy link
Contributor Author

Opened #6218 to track reuse of the local server. There is #6168 tracking the reuse of the Git credential helper.

Closing the investigation for this milestone. Thanks.

@github-actions github-actions bot locked and limited conversation to collaborators Mar 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
containers Issue in vscode-remote containers plan-item A plan item
Projects
None yet
Development

No branches or pull requests

4 participants