HorlogeSkynet / SSHubl

:technologist: A Sublime Text 4+ plugin for your SSH connections
https://packagecontrol.io/packages/SSHubl
GNU General Public License v3.0
3 stars 0 forks source link

Windows support #24

Open kapitanluffy opened 2 months ago

kapitanluffy commented 2 months ago

I get this error. I checked Lib/python38 and it has pexpect

Traceback (most recent call last):
  File "C:\Program Files\Sublime Text\Lib\python38\sublime_plugin.py", line 325, in reload_plugin
    m = importlib.import_module(modulename)
  File "./python3.8/importlib/__init__.py", line 127, in import_module
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 868, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "C:\Users\abc\AppData\Roaming\Sublime Text\Installed Packages\SSHubl.sublime-package\main.py", line 29, in <module>
  File "C:\Users\abc\AppData\Roaming\Sublime Text\Installed Packages\SSHubl.sublime-package\sshubl/commands.py", line 12, in <module>
  File "C:\Users\abc\AppData\Roaming\Sublime Text\Installed Packages\SSHubl.sublime-package\sshubl/actions.py", line 17, in <module>
  File "C:\Users\abc\AppData\Roaming\Sublime Text\Installed Packages\SSHubl.sublime-package\sshubl/ssh_utils.py", line 13, in <module>
  File "C:\Users\abc\AppData\Roaming\Sublime Text\Lib\python38\pexpect\pxssh.py", line 23, in <module>
    from pexpect import ExceptionPexpect, TIMEOUT, EOF, spawn
ImportError: cannot import name 'spawn' from 'pexpect' (C:\Users\abc\AppData\Roaming\Sublime Text\Lib\python38\pexpect\__init__.py)
HorlogeSkynet commented 2 months ago

Hello @kapitanluffy, so it appears pxssh isn't supported on Windows (see pexpect/pexpect#567 or pexpect/pexpect#339). We'll try to come out with a native workaround.

HorlogeSkynet commented 3 weeks ago

Hello there, please see #25 for implementation proposal :bow:

kapitanluffy commented 3 weeks ago

Hello there, please see #25 for implementation proposal 🙇

Thank you so much for trying to fix it! I will try to test it personally later but I looked into the code and the workaround seems fine 👍

I hope you don't mind me "approving" the PR 😅

kapitanluffy commented 3 weeks ago

I get this error @HorlogeSkynet

Capture

HorlogeSkynet commented 2 weeks ago

Thanks for trying this out @kapitanluffy ! It looks like we've precisely fallen in shlex.quote (used by shlex.join) pitfall on non-POSIX platforms, which eventually causes ssh command line parsing issues (mainly due to whitespaces in sockets directory path).

Unfortunately mslex isn't packaged for Sublime. I was on the verge of vendoring it, but it's licensed under Apache v2, so I don't know whether we actually can redistribute it under GPL v3 in SSHubl... We could also prepare a repository for inclusion in Package Control default channel.

Tell me what you think about that ! Bye :wave:

HorlogeSkynet commented 2 weeks ago

So I've browsed the WWW and it appeared doing so should be okay in our case. I've vendored mslex in #25 using a Git subtree and included the upstream Apache v2 LICENSE file to clearly mention GPL v3 doesn't apply to code present in this directory.

Could you pull the branch and give another try ? :upside_down_face:

kapitanluffy commented 2 weeks ago

So I thought maybe there's something wrong with my current setup so I tested it on a fresh install. It logged the same thing (I didn't remove my user@x.x.x.x in this screenshot)

image

It has a different error here though

getsockname failed: Not a socket
Timeout, server 192.168.1.120 not responding.
process is terminated with return code 255.

In my regular sublime, it says

command-line line 0: keyword controlpath extra arguments at end of line
process is terminated with return code 255.

Not sure if that helps 😅

Also, the server I am connecting to has a password. I was not asked about it. Based on the gif in the readme, I assume it would ask me. I did try user:pass@host too but pressing enter does nothing (no terminus view, input panel is still there)

kapitanluffy commented 2 weeks ago

Investigated further and for the Not a socket error, it seems like the socket file is not being created.

The keyword controlpath extra arguments at end of line error seems to be because of the socket file's path having spaces.

I've put below the commands it generated and I ran it in my terminal and it gave the same errors shown in the terminus view

image

# Not a socket
ssh -llupi -p22 -oServerAliveInterval=15 -oControlMaster=auto -oControlPath=D:\\area51\\sublime_text_build_4183_x64\\Data\\Cache\\SSHubl\\sockets\\9b945c3f-f4d7-439a-9b3a-6b7ccc5d542f -oControlPersist=60 192.168.1.120

# keyword controlpath extra arguments at end of line
ssh -llupi -p22 -oServerAliveInterval=15 -oControlMaster=auto "-oControlPath=C:\\Users\\xxx\\AppData\\Local\\Sublime Text\\Cache\\SSHubl\\sockets\\b64ddea6-6699-4bfd-9eaa-cfbeec72ca65" -oControlPersist=60 192.168.1.120

btw, if you need more active help in building your plugins, there's an active community in Discord that can help you out 👉 http://discord.sublimetext.io/

HorlogeSkynet commented 2 weeks ago

Thanks for debugging this out @kapitanluffy :pray:

So there are (still) two issues here :

I fear SSHubl won't be compatible with Sublime on Windows while Win32-OpenSSH doesn't support this core feature we rely upon in SSHubl internals...


Also, the server I am connecting to has a password. I was not asked about it. Based on the gif in the readme, I assume it would ask me. I did try user:pass@host too but pressing enter does nothing (no terminus view, input panel is still there)

The Gif shows a "non-interactive connection". In case of "interactive connections" (which eventually we might support for Windows), OpenSSH will ask for password directly in a Sublime view.

btw, if you need more active help in building your plugins, there's an active community in Discord that can help you out 👉 http://discord.sublimetext.io/

It's mostly help with Windows that we need :clown_face:

kapitanluffy commented 2 weeks ago

I fear SSHubl won't be compatible with Sublime on Windows while Win32-OpenSSH doesn't support this core feature we rely upon in SSHubl internals...

Is it not possible to not use ControlMaster feature?

HorlogeSkynet commented 2 weeks ago

Is it not possible to not use ControlMaster feature?

Unfortunately not.
We built SSHubl internals on this feature for connection re-use and persistence purposes. Each command interacts with "Control Master" socket to open/close a new SSH channel. Socket is even passed to sshfs to abstract "remote folders opening" from connection/authentication flows. "Down" detection feature (which triggers reconnection) also uses it.

As most of https://github.com/PowerShell/Win32-OpenSSH/issues/1328 participants, I fail to see how an official OpenSSH port for Windows can actually miss such a core feature (which was even redacted from project roadmap) :roll_eyes:

I'll push a patch for the remaining quoting issue and I guess we'll merge #25 "interactive connection" command so SSHubl will be compatible with Windows once an OpenSSH implementation starts supporting "Control Master"...

Thanks, bye :wave:

kapitanluffy commented 2 weeks ago

I see. Unfortunately, I don't think that will get supported since afaik Windows is treating sockets way differently unlike unix systems that treat everything as files.

I do use sshfs but to mount remote fs using winfsp. Not sure if you have seen this or if this will help.

https://github.com/winfsp/sshfs-win

HorlogeSkynet commented 2 weeks ago

I do use sshfs but to mount remote fs using winfsp. Not sure if you have seen this or if this will help.

Yes, we actually counted on Win32-OpenSSH to provide more or less ssh.exe as well as SSHFS-Win to provide sshfs.exe, to mimic UNIX behavior with ssh and sshfs (to keep things simple and abstract platform discrepancies).


On the quoting issue, I've followed the rabbit down the hole and here's what I've found :

cd sshubl/ && python3
import os; import subprocess; import shlex; import vendor.mslex as mslex

# fake arguments taken from your example
args = mslex.join(['ssh', '-oControlPath=C:\\Users\\xxx\\AppData\\Local\\Sublime Text\\Cache\\SSHubl\\sockets\\b64ddea6-6699-4bfd-9eaa-cfbeec72ca65'])
# args =
'ssh "-oControlPath=C:\\Users\\xxx\\AppData\\Local\\Sublime Text\\Cache\\SSHubl\\sockets\\b64ddea6-6699-4bfd-9eaa-cfbeec72ca65"'

# Now we move to Terminus internals :
def shlex_split(shell_cmd):
    # it is a version of shlex.split which supports trimming quotes and windows path
    args = shlex.split(shell_cmd, posix=False)
    for i, a in enumerate(args):
        if a.startswith('"') and a.endswith('"'):
            args[i] = a[1:-1]
        elif a.startswith("'") and a.endswith("'"):
            args[i] = a[1:-1]
    return args

cmd_to_run = ["cmd.exe", "/c"] + shlex_split(args)
# cmd_to_run =
['cmd.exe', '/c', 'ssh', '-oControlPath=C:\\Users\\xxx\\AppData\\Local\\Sublime Text\\Cache\\SSHubl\\sockets\\b64ddea6-6699-4bfd-9eaa-cfbeec72ca65']

# And now we move to PyWinPTY internals :
cmdline = subprocess.list2cmdline(cmd_to_run[1:])
# cmdline =
'/c ssh "-oControlPath=C:\\Users\\xxx\\AppData\\Local\\Sublime Text\\Cache\\SSHubl\\sockets\\b64ddea6-6699-4bfd-9eaa-cfbeec72ca65"'

So my guess is that we're struggling with cmd.exe/Microsoft internals, which concatenates all arguments as a single one, so this fails afterwards (when ssh.exe actually does its parsing) due to the space present in socket path.

I don't know whether we should merge #25 "as is", as new interactive connection command does work on Linux/macOS and keep this parsing issue for later, or we should wait for/find a fix for this Terminus/PyWinPTY/Microsoft integration issue beforehand...

EDIT : maybe related to randy3k/Terminus#342


I've also updated #25, mostly to bump mslex to v1.3.0 that has been released some days ago.


Thanks, bye :wave:

kapitanluffy commented 2 weeks ago

Sure, merge it since it seems to be a big chunk of significant improvements even without the windows stuff.

What I do suggest is that either remove the windows support or find a way to make it work even if it does not use the ControlMaster feature or even if it is not as optimal as the nix counterpart. IMO, that feature will not be supported in Windows because of how it depends on how Linux inherently works (sockets as files).

Feel free to close this issue. Thank you so much for the effort put into this 🙏

HorlogeSkynet commented 1 week ago

Sure, merge it since it seems to be a big chunk of significant improvements even without the windows stuff.

Will do, once we've checked with @d3vyce there isn't a "quick win" for the quote issue.

What I do suggest is that either remove the windows support or find a way to make it work even if it does not use the ControlMaster feature or even if it is not as optimal as the nix counterpart. IMO, that feature will not be supported in Windows because of how it depends on how Linux inherently works (sockets as files).

Strictly speaking, SSHubl will (with #25) be compatible with Windows. It won't be with Win32-OpenSSH though :clown_face: If an OpenSSH implementation happens to support "Control Master" feature (one way or the other), SSHubl should work OOTB.

(I've noticed your comment on https://github.com/PowerShell/Win32-OpenSSH/issues/405, and we'll also follow this thread, if a workaround that we could implement here at a little cost is proposed)

Feel free to close this issue.

Let's keep it open for the time being, to clearly mention there is an ongoing issue with SSHubl/OpenSSH/Windows integration.

Thank you so much for the effort put into this 🙏

Thanks for your message ! We thank you again for your time (and we hope, future trials :wink:).