platformsh / legacy-cli

This is the legacy version of Platform.sh's command-line interface. The new version is at: https://github.com/platformsh/cli
https://docs.platform.sh/administration/cli.html
MIT License
221 stars 121 forks source link

Support opening an SSH tunnel to XDebug #638

Open tylers-username opened 6 years ago

tylers-username commented 6 years ago

I'd like to have the ability to map custom ports (in my case, for XDEBUG).

So, something like platform tunnel:open 9000 which would then map to a port based on the clients current port mapping logic (i.e. 30009).

I'm happy to contribute to this, however, what is the preferred method?

  1. Adding a custom mapping argument?
  2. Or, since tunnel currently cycles through relationships being able to add XDEBUG as a relationship/service?
pjcdawkins commented 6 years ago

[Just adding context for now, I'll think about how best to support this]

For new tunnels, currently, the port is selected as the next available port number, starting from 30000.

https://github.com/platformsh/platformsh-cli/blob/9c12360f5dba1470a2b943bc7267a6fb1fe08263/src/Command/Tunnel/TunnelOpenCommand.php#L78 https://github.com/platformsh/platformsh-cli/blob/9c12360f5dba1470a2b943bc7267a6fb1fe08263/src/Command/Tunnel/TunnelCommandBase.php#L151-L159 https://github.com/platformsh/platformsh-cli/blob/9c12360f5dba1470a2b943bc7267a6fb1fe08263/src/Util/PortUtil.php#L84-L93

tylers-username commented 6 years ago

Since this can be so wide open and there are so many variations in how ports may become available, making this a poor choice for relationships, maybe the appropriate flow is: platform tunnel:open --app=[application] --app-port=[application port]

If my application is called "Laravel" and I want a tunnel to port 9000: platform tunnel:open --app=laravel --port=9000.

If the next available port is 30005, then we now have: 127.0.0.1:30005 => laravel:9000

Edit I'm sure "environment" is more appropriate than "application".

For development purposes, it might be a good option to have a "--match" flag that would force the ports to match. So, in this case 9000 would map to 9000.

pjcdawkins commented 6 years ago

The command opens tunnels for 1 application (inside 1 environment). Each application can have multiple relationships (to services, e.g. mysql + redis), and the command opens tunnels for all of those relationships. Each of those tunnels needs a local port number.

But we might need to go back a step here. You can't control what the remote port number would be: you can't have an application listening on port 9000 at the moment (unless there's something I've missed). Some kind of remote Xdebug service would be nice, but I think if we offered it, it would be something we'd implement with a simplified API.

tylers-username commented 6 years ago

Xdebug is a PHP extension which, by default, uses port 9000. Xdebug is supported by Platform.sh. We use it today. Currently, we communicate with it by using SSH to tunnel to the application at 9000.

pjcdawkins commented 6 years ago

Oops, I didn't realise we did that yet. That will need a special case implementation in the CLI, as far as I can see.

QuingKhaos commented 4 years ago

Some notes: XDebug doesn't run on port 9000 in the app. Xdebug connects to by default localhost:9000, which is the opposite direction of the tunnel:open command.

tunnel:open uses i.e. ssh -L 30000:database.internal:3306 and opens a local tunnel (creates a listening port on your machine), so you can connect on the local port 30000, which is forwarded to the apps relationships port database.internal:3306.

For XDebug you need to use an remote tunnel with ssh -R 9000:localhost:9000, which opens a remote tunnel in the app (creates a listening port in the app container), so xdebug can connect on port 9000 on the container to your IDE on port 9000.

Varying ports are not nice for xdebug, as you have to set the xdebug port in the IDE to listen to it.

tylers-username commented 4 years ago

@emiikhaos and I think devs expect this. That means from platform.sh's perspective, the cli only needs to use that port. If it can't open it, let the dev know it's already in use.

QuingKhaos commented 4 years ago

Still, tunnel:open works in the opposite direction as xdebug needs. I wouldn't expect an inconsistent behavior when using the command. Especially I wouldn't expect to get warning when using it in two projects.

I would recommend two new commands like xdebug:start and xdebug:stop to establish the remote tunnel for port 9000. So it has its own consistency and you know you have to stop another one before starting to use it in the second project.