coder / jetbrains-coder

A JetBrains Plugin for Coder Workspaces
MIT License
26 stars 12 forks source link

One-click experience to Gateway from Coder dashboard #149

Closed bpmct closed 1 year ago

bpmct commented 1 year ago

Coder has a "VS Code Desktop" button which does the following:

  1. Open the user's VS Code
  2. Install the Remote SSH extension, if not installed
  3. Install the Coder Remote extension, if not installed
  4. Logs in the user
  5. Starts workspace name, if unstarted
  6. Connects to workspace name

We'd love to add an icon for JetBrains Gateway as well, but am not sure how much the Gateway API will let us support. Some open questions:

fioan89 commented 1 year ago

I did some research, played with Gateway and my thoughts on this topic are:

  • Can we link to SSH for specific IDEs instead of requiring the dedicated gateway (e.g. SSH tab in Goland)?
    • I noticed you can still install "Coder Gateway" for Goland

No, as far as I could debug. Seems like custom URL handling is delivered only with Gateway, but not with Remote Development feature delivered with comercial Jetbrains products. And yes, today the plugin is compatible with both Gateway and Remote Development feature from Goland.

  • Can we link to prompt the user to install the plugin?

Unfortunately no. The custom URL handling in Gateway is very limited. By default Gateway is only able to open the Jetbrains Client from an SSH or WSL connection type. Plugins can extend this functionality by registering an implementation for GatewayUrlHandler . But even if that is done, the Gateway API doesn't allow much else than starting the Jetbrains Client. The navigation between different steps of the Gateway UI is limited and controlled internally by Gateway API.

However I did submit two requests to Jetbrains to extend the API:

https://youtrack.jetbrains.com/issue/GTW-3223/Gateway-custom-URL-handler-to-install-plugins https://youtrack.jetbrains.com/issue/GTW-3224/API-to-programmatically-start-the-GatewayConnectorView

The first one requests the ability to install plugins through a URL handler, while the second one requests more permissive programmatic actions, especially screen navigation.

Main take: if the plugin is not installed then the very limited URL handling provided by Gateway does not help us.

  • Once installed, can we create links that send data to the plugin (e.g. user token, Coder URL, workspace ID?
    • I know Gateway has some query parameter support

Short story - yes. Long story, as I mentioned above, we would have to implement our custom URL handler, but what we can do is limited, but certainly we can provide an implementation that parses the parameters and fires up the Jetbrains Client.

Do you think we should link to instructions around installing Gateway? It is less common than VS Code.

I think for starter we can do that. Right now - at best we can provide functionality to fire up the Jetbrains Client from a URL with Coder parameters. If Jetbrains fixes the two requests I made then I think we can fully implement your requests.

fioan89 commented 1 year ago

jetbrains-gateway://connect#idePath=%2Fhome%2Fcoder%2F.cache%2FJetBrains%2FRemoteDev%2Fdist%2F18f9d3a75032e_pycharm-professional-231.4840.379&projectPath=%2Fhome%2Fcoder%2FdirBob&host=Bob&port=22&user=coder&type=ssh&deploy=false

This is how a custom URL looks like for opening a Coder Workspace with the SSH connector, in the Jetbrains Client.

code-asher commented 1 year ago

I was poking around Gitpod and when you click their "Open in IntelliJ IDEA" button from the dashboard on the web you get prompted to install the Gitpod extension in Gateway and then it downloads IDEA and launches it (no interaction from me).

My guess is the Gitpod URL handler must be hard-coded on the Gateway side? Would make sense seeing as it shows up as one of the default providers. If so I wonder if we can get this for Coder.

I also experimented with the jetbrains-gateway:// URL to use the SSH connector but it seems not to work unless idePath is specified and I am not sure how we would reliably know the path on the dashboard side. It would be neat if we could just put pycharm for example but it executes <idePath>/bin/remote-dev-server.sh so no luck there.

And I suppose this would require that you already have SSH set up but we could document that.

fioan89 commented 1 year ago

That's weird. The experience that I had was that there were instructions on the webpage to manually install the plugin. When I clicked the button to open a project in IntelliJ, Gateway was started and an error was raised if the plugin was missing. image

fioan89 commented 1 year ago
2023-02-15 12:20:23,301 [   2286]   INFO - #c.i.i.CommandLineProcessor - external URI request:
jetbrains-gateway://connect/#gitpodHost=gitpod.io&workspaceId=fioan89-sourcesync-fnfjjpxysj9&backendPort=63342&debugWorkspace=false
2023-02-15 12:20:23,364 [   2349] SEVERE - #c.i.i.CommandLineProcessor - Can not find connection provider
java.lang.Exception: Can not find connection provider
    at com.jetbrains.gateway.api.GatewayConnectionProvider$Companion.connect(GatewayConnectionProvider.kt:15)
    at com.jetbrains.gateway.impl.GatewayConnectionHandler.tryConnect(GatewayConnectionHandler.kt:23)
    at com.jetbrains.gateway.GatewayProtocolHandler.process(GatewayProtocolHandler.kt:38)
    at com.intellij.ide.ProtocolHandler.process(ProtocolHandler.java:34)
    at com.intellij.ide.CommandLineProcessor$1.run(CommandLineProcessor.java:181)
    at com.intellij.openapi.progress.impl.CoreProgressManager.startTask(CoreProgressManager.java:442)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.startTask(ProgressManagerImpl.java:114)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcessWithProgressAsynchronously$5(CoreProgressManager.java:493)
    at com.intellij.openapi.progress.impl.ProgressRunner.lambda$submit$3(ProgressRunner.java:252)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:188)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$12(CoreProgressManager.java:608)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:683)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:639)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:607)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:60)
    at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:175)
    at com.intellij.openapi.progress.impl.ProgressRunner.lambda$submit$4(ProgressRunner.java:252)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
    at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
    at java.base/java.lang.Thread.run(Thread.java:833)
fioan89 commented 1 year ago

The plugins can somehow be semi-automatically installed through installPlugins shipped with Gateway https://www.jetbrains.com/help/idea/managing-plugins.html#install_plugin_cmd. In theory this command could be orchestrated from a webpage

code-asher commented 1 year ago

Oh interesting, yeah when I ran it Gateway launched and a dialog popped up asking if I wanted to install the Gitpod extension. Could this be recent addition? I think I was using the latest version of Gateway.

I also learned that supposedly we can exclude idePath for the SSH connector if we set deploy to true and include buildNumber and productCode although apparently that is not actually implemented yet (at least as of nine months ago).

bpmct commented 1 year ago

Going to remove the blocked label for now since it seems they claimed this is possible now.

matifali commented 1 year ago

Related https://github.com/coder/coder/discussions/7729