Vscode-remote-release: Enable custom shell initialization script on the remote

Created on 5 May 2019  路  25Comments  路  Source: microsoft/vscode-remote-release

The system where I would use the Remote SSH feature has a quite "vintage" tool setup by default, which causes installation of the extension to fail. By modifying my .bashrc I am able to work around this with generous use of module add, but now my whole environment is "non-standard", and build tools ding me for this, even if I'm not using Code. I'm sure that at some point I will spend days looking for a bug caused by me swapping out the core GNU tooling for a different version.

I suggest adding the possibility to specify a script that is sourced on the remote before executing the installation and launching the extension server. It doesn't have to be a setting, just a script with a known name. This would put the remote tools on equal footing with the IDE itself, where i am able to run code inside a custom environment by sourcing a setup script first, without having to "pollute" my .bashrc.

This request might be slightly related to #83.

feature-request plan-review ssh

Most helpful comment

@juanrh describes the situation very well. The key issue is that when running Code in the traditional local mode, you always have the option of launching it from a shell where you've prepared the environment for the various plugins, but this possibility is lost in remote mode. (In my case, the installer won't even run unless I modify my .bashrc to swap out the GNU tooling.)

The only workaround that I can think of, modifying my .bashrc for developing a specific project, is bound to cause problems and makes it impossible to open two projects in parallel.

All 25 comments

This might also be useful for ROS development, as running source on a setup.bash file` is part of the basic development cycle

Can you explain some more about what you are looking for? Is this about running the rc file for some non-bash shell? If so that should work now. Or running a custom arbitrary script which would not normally be run for an ssh session?

It would be more the second thing, "running a custom arbitrary script which would not normally be run for an ssh session".

In ROS there is this concept of workspace overlay that is used to extend the set of ROS packages available at build time and at runtime. The base workspace corresponds to your ROS installation, usually in /opt/ros/${ROS_DISTRO} (e.g. /opt/ros/kinetic), and is activated by running source /opt/ros/${ROS_DISTRO}/setup.bash. That source command can be added to ~/.bashrc, but often it isn't because you can have different ROS distributions installed in your workstation, and use that source command to activate the different distros. This is because often ROS packages are supported in several distributions (see e.g. https://index.ros.org/p/ros2launch/), and having several ROS distros installed is useful for development.

But even if you only have a single ROS distribution installed in your workstation, you'll probably have several ROS workspaces. A ROS workspace is a project folder where you develop several ROS packages. There is a standard directory layout in a workspace, where a src directory contains the code, a build directory contains the temporary files for CMake builds, and an install directory contains the installed binaries. The src directory contains the source code for several ROS packages, that are directories with a file package.xml and also different files depending on the language used to implement the package, which is usually either Python or C++ (based on CMake). You have to run source install/setup.bash to add the artifacts in your local workspace to the scope for building and running. That source command "overlays" the local workspace on top of the base workspace that corresponds to the active ROS distro. So a typical development workflow in ROS is something as follows:

cd ~/myworkspace
# activate a ROS distro
source /opt/ros/kinetic/setup.bash
# run build commands: this creates the `install` directory 
colcon build 
# run unit tests
colcon test 
# activate local workspace
source install/setup.bash
# launch a program "bar" installed in the package "foo"
roslaunch foo bar

When I have used vscode to develop C++ packages in ROS, which are based on CMake, I usually do source /opt/ros/kinetic/setup.bash && colcon build && source install/setup.bash and then I launch vscode, and use the extension CMake Tools on a specific C++ ROS package in the workspace. But if I skip source install/setup.bash or launch vscode without the env vars defined by that source, then the plugin doesn't work, because that source is configuring several env vars that are expected by the CMake scripts used by the ROS build system (see e.g. https://github.com/ros/catkin/tree/kinetic-devel/cmake), and that are used to switch between workspaces.

@juanrh describes the situation very well. The key issue is that when running Code in the traditional local mode, you always have the option of launching it from a shell where you've prepared the environment for the various plugins, but this possibility is lost in remote mode. (In my case, the installer won't even run unless I modify my .bashrc to swap out the GNU tooling.)

The only workaround that I can think of, modifying my .bashrc for developing a specific project, is bound to cause problems and makes it impossible to open two projects in parallel.

Ok, thanks I think I understand. I will have to think about this. One solution could be an extension that runs the script on startup and modifies the extension host environment.

Would an extension be capable of modifying the environment required to install the extension host in the first place? Does it have to be an extension instead of a step in the launch script for the extension host (assuming that it is a sh script in the first place)?
Thanks for giving this some thought!

An extension can only modify the extension host's environment after it is already running, which may or may not work for whatever CMake Tools is doing.

If the environment is specified by a shell script, would the extension realistically be able to modify the environment of the running Node process short of coming up with some in-process sh interpreter? (I'm sorry if I have misunderstood how the extension would operate.)

process.env can be modified, and this would be the same environment that other extensions see. The extension would have to figure out how the shell script modified the environment, probably you would have to modify the shell script to write output that the extension can parse. For example it can write

FOO=bar

and the extension can read that and write process.env['FOO'] = 'bar'.

It can even invoke node to JSON.stringify the environment, read that output, parse it, and copy it into the extension hosts' process.env. We do something that like that here:

https://github.com/microsoft/vscode/blob/20ec76e47b427507141565aa75a0a599e9539d1d/src/vs/code/node/shellEnv.ts#L28

But yeah this would take some extra effort to set up but it might be something that can unblock you.

It's hard to think about how this would work as a builtin feature because we avoid features that tell vscode to run an arbitrary script just by opening a folder. Like if this existed, it would be disabled by default and something that you have to clearly opt in to per-workspace.

Oh and another solution, we should get this to work if you

  • open another remote folder, or an empty window on that remote
  • Run the script in the integrated terminal
  • Then run code-insiders <workspace> in the terminal

@Tyriar tldr:
would it make sense, when launching vscode with the remote cli, to have the new remote EH somehow get the environment of the terminal from where it was launched? I think we would have to send the full environment along with the command to launch a new window.

@roblourens there are issues around this in the vscode repo:

I don't think the remote stuff should differ from local until https://github.com/microsoft/vscode/issues/15452 is actioned.

Oh ok. 15452 makes sense but then I don't know how it will work for the use case above. Probably the extension just needs to set up its environment for itself.

I wouldn't mind a solution that required some manual step to have the proper initialization run, because this is already the case when I "source my dev environment" before launching the IDE. However, if it involves modifying the environment _after_ the server has launched, it won't work. For instance, after successfully getting a large corporation to change their SSH security settings to allow VS Code port forwarding (I can tell you the remote extension is making waves here), I'm now stuck because of #103. I need a newer GLIBCXX, but modifying LD_LIBRARY_PATH in my .bashrc is a non-starter. Also, I'm fairly certain the failure happens so early that an extension patching up the Node environment wouldn't help.

I understand why you want to avoid running any code automatically by simply opening a folder, so this shouldn't simply be a workspace setting. Would it be possible to pass options from the local Code instance to the server? Or, could the SSH session used to launch the server optionally be started in interactive mode attached to a terminal, so I can do whatever setup is needed and then launch the server process by running code from there?

FYI for anyone trying to use the CMake Tools extension within a window spawned from this extension, there's an open feature request to allow CMake Tools to source a setup script before running.

I made a workaround script. Use at your own risk.

+1 My use case is to enable conda's (or other package or container management) build environment for a vscode project

+1 must have feature for ssh-remote to work with ROS

Right now default build won't work since for some reason catkin_make showing "no such file or directory"

+1 also in high energy physics the most common workflow would be to delegate the environment setup to a single bash script, and this issue is a blocker for remote working with vscode

To be clear, you can still use .bashrc or .profile or whatever you would normally do for your environment. This feature request is for a script to do vscode remote-ssh specific configuration that you don't want in a normal shell on that host.

This is a must have feature when working with software collections on red hat enterprise or cent OS to enable more recent compilers. Editing the .bashrc does not seem to be sufficient for me. Extensions don't seem to source this script.

Any updates on this?

To be clear, you can still use .bashrc or .profile or whatever you would normally do for your environment. This feature request is for a script to do vscode remote-ssh specific configuration that you don't want in a normal shell on that host.

Does it actually honour .profile? I have a source script.sh line in my .profile; this gets executed when I ssh in from Windows Terminal, but not when I go in via VS Code.

It is also very difficult to use vs code without this feature with clusters, since everything will be running on the login node (see #2808).

To be clear, you can still use .bashrc or .profile or whatever you would normally do for your environment. This feature request is for a script to do vscode remote-ssh specific configuration that you don't want in a normal shell on that host.

Yes, but as far as I understand code in .bashrc cannot distinguish between normal interactive run and connection via vs code If the remote extension would set some environment variable, that would already help in majority of the use-cases, I believe.

E.g., using something similar to RemoteCommand VSCODE_REMOTE_SESSION=1 bash (see #158).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Arunselvan-AS picture Arunselvan-AS  路  3Comments

tianomagdaong picture tianomagdaong  路  3Comments

kieferrm picture kieferrm  路  3Comments

grzegorz-silarski picture grzegorz-silarski  路  3Comments

sulume picture sulume  路  3Comments