Vscode-remote-release: Published "appPorts" are not reused when opened using serverReadyAction (and likely vscode.env.openExternal / asExternalUri)

Created on 8 Nov 2019  路  12Comments  路  Source: microsoft/vscode-remote-release

Currently it appears that if you use the appPort property in devcontainer.json, the port is not reused if launched from serverReadyAction in launch.json. This is likely the case with vscode.env.openExternal and vscode.env.asExternalUri as well.

Simple repro:

  1. Clone the latest https://github.com/microsoft/vscode-remote-try-dotnet repo
  2. Open folder in container
  3. Add the following to launch.json
    json "serverReadyAction": { "action": "openExternally", "pattern": "^\\s*Now listening on:\\s+https?://(?:\\[::\\])?\\S*:(\\S+)", "uriFormat": "http://localhost:%s" }
  4. F5

Expected: A browser window pointing to http://127.0.0.1:5000 appears
Actual: Browser opens http://127.0.0.1:<random port>

The random port appears to be due to the fact that 5000 is already in use - which is true because devcontainer.json includes "appPort":[5000,5001] and the web application is listening on 5000 already.

This might happen with SSH for ports that were forwarded using ~/.ssh/config as well.

//cc: @mjbvz @chrmarti

containers feature-request verification-needed verified

Most helpful comment

@alexr00 I guess if the remote port is the same as in the existing forwarding, couldn't that be reused?

All 12 comments

The resolver will need a way to tell the core that a certain port is being forwarded.

@alexr00 The extension now tells the core which ports are being forwarded, so this would seem to be possible to implement. Maybe it already is?

The ITunnelService allows you to get the tunnels which returns an array of RemoteTunnels that debug could check, but we don't keep track of the "source" of the forward. I'm not sure this matters. @weinand would you want a source to check against? A tunnel could exist for several reasons:

  • an extension forwarded a port
  • there was an API call to openExternal or resolveExternal
  • the user forwarded a port

@alexr00 Couldn't the the tunnel service return the existing local port when there already is one?

No, since if the request to open a tunnel comes from any of the sources we do need to use a different port.

Which sources and why can't the existing tunnel not be reused?

In the case that the source is the user: If the user is trying to forward and using local port 5000 and we see that they there is already a tunnel using 5000 then we should pick a different local port.

@alexr00 I guess if the remote port is the same as in the existing forwarding, couldn't that be reused?

I agree, we should be able to do that.

One limitation of appPort is that its local endpoint is on the machine where the Docker daemon runs. Maybe the extension should not return these ports when the connection is not to a socket path (as a heuristic) since the 'open' action also wouldn't work if the daemon runs remotely.

Updated Remote-Containers to only return exposed ports as existing tunnels if DOCKER_HOST is not set (otherwise assuming they are exposed on another machine).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

peterkappelt picture peterkappelt  路  3Comments

6XAM picture 6XAM  路  3Comments

sulume picture sulume  路  3Comments

abdullahiabdirahman picture abdullahiabdirahman  路  3Comments

JacksonKearl picture JacksonKearl  路  3Comments