Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

edit remote files via tramp - emacs freez and other issues #758

Closed
Moerliy opened this issue Nov 1, 2023 · 18 comments
Closed

edit remote files via tramp - emacs freez and other issues #758

Moerliy opened this issue Nov 1, 2023 · 18 comments
Labels
help wanted Extra attention is needed

Comments

@Moerliy
Copy link
Contributor

Moerliy commented Nov 1, 2023

I was trying to use lsp-bridge to edit a remote project via ssh and tramp. Tramp itself works, the lsp server and lsp-bridge is installed on the ssh-host and lsp-bridge.py is running.

When i open a remote file via tramp lsp-bridge asks me for the ssh host's password. When i provide this emacs freezes up. When i open another emacs session (i'm running emacs with a daemon in the background), the old one stops freezing and when i start typing inside the oped file, lsp-brideg asks again for my ssh-host's password. If I type it in again it will not freeze up but there will be no connection to the lsp-bridge running on the ssh-host.

*lsp-bridge* buffer

Traceback (most recent call last):
  File "MYHOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 178, in send_message_dispatcher
    client = self.get_socket_client(data["host"], port)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "MYHOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 394, in get_socket_client
    client = RemoteFileClient(
             ^^^^^^^^^^^^^^^^^
  File "MYHOME/.config/emacs/elpaca/repos/lsp-bridge/core/remote_file.py", line 47, in __init__
    self.chan = self.transport.open_channel("direct-tcpip", (self.ssh_host, self.server_port), ('0.0.0.0', 0))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'open_channel'

I should mention that i have a ssh key-pair working with the ssh-machine and it works like it should but not with lsp-bridge. I also have a config for the ssh host in ssh/config.

Host NAME
    Hostname HOST-IP
    User USR
    Compression yes
    ForwardX11Trusted yes
    ProxyJump JUMP-USR@JUMP-IP

My wild guess is that lsp-bridge is not the biggest fan of jump connections with ssh.

@manateelazycat
Copy link
Owner

lsp-bridge can works if you ssh login server directly, I guess something wrong with proxy server.

I'm not good at using multi-level server, welcome to send patches

@manateelazycat manateelazycat added the help wanted Extra attention is needed label Nov 2, 2023
@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 2, 2023

All right. If I got the time i will have a look into it. Maybe I will come back with some questions regarding the lsp-bridge code in general.

@manateelazycat
Copy link
Owner

I push commit: https:github.com/manateelazycat/lsp-bridge/commit/2fe97d91db938ac70ee59a11d1eacc23f6697199

This patch will print an error message in the 'lsp-bridge' buffer when the login is incorrect, you can try it and see what error is reported?

Maybe it's lsp-bridge's internal library that uses paramiko doesn't support jump servers

@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 2, 2023

This patch will print an error message in the 'lsp-bridge' buffer when the login is incorrect, you can try it and see what error is reported?

Appreciated

Maybe it's lsp-bridge's internal library that uses paramiko doesn't support jump servers

I think so too. I had a quick look into it and a proxy command support came out later. I found something in there docs.

@werhner
Copy link
Contributor

werhner commented Nov 8, 2023

For now lsp-bridge's internal library doesn't support jump servers. My work scenario also requires the use of jump servers. If lsp-bridge supports jump server, it can support more remote editing scenarios.

@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 8, 2023

@werhner I need it ... so I started writing and tinkering with the internals.
Getting a bare bone implementation that makes use of the .ssh/config should work. Doesn't require much lisp code and the python code changes are moderat as well. The library "paramiko" that is used by the internals has support for ProxyCommands but the documentation on it is very scares and I haven't managed to get it running yet.
I have an issue open over at paramiko/paramiko but still no reply unfortunately.

Help is definitely welcome and probably needed. Especially later one for the lisp code 😅.

@werhner
Copy link
Contributor

werhner commented Nov 9, 2023

Thank you for providing information about the ProxyCommand function. I have written a patch that supports jump server.

you should change the ProxyJump option in ssh/config to the following ProxyCommand option

ProxyCommand ssh -qW %h:%p JUMP-USR@JUMP-IP

You can give it a try. Thank you.

@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 9, 2023

@werhner connection to the ssh host now works but I'm getting some errors when my emacs lsp-bridge and the lsp-bridge that runs on the ssh host try to communicate.
I'm not sure if this is related to the proxy change or a completely different problem and should be tracked in another issue.

Emacs *lsp-bridge* output:

--- [14:57:29.319523] Receive remote message: {"command": "get_emacs_vars", "args": ["tabnine-bridge-binaries-folder"], "host": "141.3.88.138"}
Exception in thread Thread-12:
Traceback (most recent call last):
  File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
    self.run()
  File "$HOME/.config/emacs/elpaca/repos/lsp-bridge/core/remote_file.py", line 100, in run
    self.callback(message)
  File "$HOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 416, in <lambda>
    lambda message: self.receive_socket_message(message, server_port),
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "$HOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 439, in receive_socket_message
    client = self.get_socket_client(host, REMOTE_FILE_ELISP_CHANNEL)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "$HOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 413, in get_socket_client
    self.host_names[server_host]["username"],
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: '141.3.88.138'

ssh host's lsp-bridge.py terminal output:

* Running lsp-bridge in remote server, use command 'lsp-bridge-open-remote-file' to open remote file.

--- [14:57:29.278537] Build connect from 141.3.88.138:49950
Traceback (most recent call last):
  File "./lsp-bridge/lsp_bridge.py", line 510, in event_dispatcher
    getattr(self, func_name)(*func_args)
AttributeError: 'LspBridge' object has no attribute '_signature_help'

Exception in thread Thread-8:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "./lsp-bridge/lsp_bridge.py", line 499, in handle_remote_request
    getattr(self, message["method"])(*message["args"])
AttributeError: 'LspBridge' object has no attribute 'search_file_words_search'

@manateelazycat
Copy link
Owner

@werhner connection to the ssh host now works but I'm getting some errors when my emacs lsp-bridge and the lsp-bridge that runs on the ssh host try to communicate.连接到 ssh 主机现在可以工作了,但是当我的 emacs lsp-bridge 和在 ssh 主机上运行的 lsp-bridge 尝试通信时,我遇到了一些错误。 I'm not sure if this is related to the proxy change or a completely different problem and should be tracked in another issue.我不确定这是否与代理更改或完全不同的问题有关,应该在另一个问题中进行跟踪。

Emacs lsp-bridge output:Emacs lsp-bridge 输出:

--- [14:57:29.319523] Receive remote message: {"command": "get_emacs_vars", "args": ["tabnine-bridge-binaries-folder"], "host": "141.3.88.138"}
Exception in thread Thread-12:
Traceback (most recent call last):
  File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
    self.run()
  File "$HOME/.config/emacs/elpaca/repos/lsp-bridge/core/remote_file.py", line 100, in run
    self.callback(message)
  File "$HOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 416, in <lambda>
    lambda message: self.receive_socket_message(message, server_port),
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "$HOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 439, in receive_socket_message
    client = self.get_socket_client(host, REMOTE_FILE_ELISP_CHANNEL)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "$HOME/.config/emacs/elpaca/builds/lsp-bridge/lsp_bridge.py", line 413, in get_socket_client
    self.host_names[server_host]["username"],
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: '141.3.88.138'

ssh host's lsp-bridge.py terminal output:SSH主机的 lsp-bridge.py 终端输出:

* Running lsp-bridge in remote server, use command 'lsp-bridge-open-remote-file' to open remote file.

--- [14:57:29.278537] Build connect from 141.3.88.138:49950
Traceback (most recent call last):
  File "./lsp-bridge/lsp_bridge.py", line 510, in event_dispatcher
    getattr(self, func_name)(*func_args)
AttributeError: 'LspBridge' object has no attribute '_signature_help'

Exception in thread Thread-8:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "./lsp-bridge/lsp_bridge.py", line 499, in handle_remote_request
    getattr(self, message["method"])(*message["args"])
AttributeError: 'LspBridge' object has no attribute 'search_file_words_search'

First error, please add print("*** ", self.host_names, server_host, server_port) in function get_socket_client, and paste log start with ***

@manateelazycat
Copy link
Owner

search_file_words_search

Second error, you need git clone lsp-bridge on server then start lsp_bridge.py, you need include all lsp-bridge files under remote server.

You will got strange error if you just copy lsp_bridge.py to some directory to start.

@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 9, 2023

First error, please add print("*** ", self.host_names, server_host, server_port) in function get_socket_client, and paste log start with ***

***  {
'$HOST': {
   'server_host': '$HOST_NAME', 
   'username': '$USER', 
   'ssh_port': [], 
   'use_gssapi': False, 
   'proxy_command': 'ssh -qW $HOST_NAME:22 $USER@$JUMP_HOST_NAME'
}, 
'$HOST_NAME': {
   'username': '$USER', 
   'ssh_port': 22, 
   'use_gssapi': False, 
   'proxy_command': 'ssh -qW $HOST_NAME:22 $USER@$JUMP_HOST_NAME'
}} 
$HOST_NAME 9997

--- [16:11:49.498121] Receive remote message: {"command": "get_emacs_vars", "args": ["tabnine-bridge-binaries-folder"], "host": "$HOST_NAME_IP_ADDRESS"}
***  {
'$HOST': {
   'server_host': '$HOST_NAME', 
   'username': '$USER', 
   'ssh_port': [], 
   'use_gssapi': False, 
   'proxy_command': 'ssh -qW $HOST_NAME:22 $USER@$JUMP_HOST_NAME'
}, 
'$HOST_NAME': {
   'username': '$USER', 
   'ssh_port': 22, 
   'use_gssapi': False, 
   'proxy_command': 'ssh -qW $HOST_NAME:22 $USER@JUMP_HOST_NAME'
}} 
$HOST_NAME_IP_ADDRESS 9997

I have to do a bit of censoring because the ip's are for work.
$HOST: The host defined in .ssh/config with Host
$HOST_NAME: The host name defined in .ssh/config with HostName
$USER: The user name defined in .ssh/config with User
$JUMP_HOST_NAME The host name used in .ssh/config in ProxyCommand
$HOST_NAME_IP_ADDRESS The numerical IPv4 address of $HOST_NAME

I also should mention that when I open the file with tramp, I get no extra output from lsp_bridge.py on my ssh host or the *lsp-bridge* buffer.
But when I refresh the buffer I opened with tramp in emacs, lsp-bridge seems to connect to the instance on the ssh host and i get the error messages.
My blind guess to why this happens is because of lsp-bridge-tramp-alias-alist.

Second error, you need git clone lsp-bridge on server then start lsp_bridge.py, you need include all lsp-bridge files under remote server.

I have the repo cloned on my ssh host. I even remembered to pull all the newest changes before I started.

@manateelazycat
Copy link
Owner

@werhner can you take a look? thanks

@werhner
Copy link
Contributor

werhner commented Nov 10, 2023

Sorry for the delayed response.
The first question seems similar to issue #769. @Moerliy, is the host name defined in .ssh/config in domain name format rather than IP format?
The second question appears to be a probabilistic issue. It seems that the local host sent a request to the remote host before it was initialized properly. I will try to provide a patch for this over the weekend.
I apologize for any inconvenience caused by this.

@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 10, 2023

The first question seems similar to issue #769. @Moerliy, is the host name defined in .ssh/config in domain name format rather than IP format?

It's defined in domain name from.

@werhner
Copy link
Contributor

werhner commented Nov 12, 2023

Change it to IP format and try again.

@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 12, 2023

The output that i get in emacs looks to be pretty similar but i get a bigger stacktrache from the console on my ssh host running the lsp_bridge py
With numerical IPv4:

--- [17:22:49.061546] Build connect from 141.3.88.138:47084
Traceback (most recent call last):
  File "./lsp-bridge/lsp_bridge.py", line 510, in event_dispatcher
    getattr(self, func_name)(*func_args)
  File "./lsp-bridge/lsp_bridge.py", line 754, in _do
    open_file_success = self.open_file(filepath)  # _do is called inside event_loop, so we can block here.
  File "./lsp-bridge/lsp_bridge.py", line 538, in open_file
    project_path = get_project_path(filepath)
  File "/common/homes/students/ughlu_gleissner/lsp-bridge/core/utils.py", line 384, in get_project_path
    if get_command_result("git rev-parse --is-inside-work-tree", dir_path) == "true":
  File "/common/homes/students/ughlu_gleissner/lsp-bridge/core/utils.py", line 285, in get_command_result
    encoding="utf-8", errors="replace")
TypeError: __init__() got an unexpected keyword argument 'text'

With domian name format:

--- [17:25:41.303238] Build connect from 141.3.88.138:50594
Traceback (most recent call last):
  File "./lsp-bridge/lsp_bridge.py", line 510, in event_dispatcher
    getattr(self, func_name)(*func_args)
AttributeError: 'LspBridge' object has no attribute '_signature_help'

@manateelazycat
Copy link
Owner

          The output that i get in emacs looks to be pretty similar but i get a bigger stacktrache from the console on my ssh host running the lsp_bridge py 

With numerical IPv4:

--- [17:22:49.061546] Build connect from 141.3.88.138:47084
Traceback (most recent call last):
  File "./lsp-bridge/lsp_bridge.py", line 510, in event_dispatcher
    getattr(self, func_name)(*func_args)
  File "./lsp-bridge/lsp_bridge.py", line 754, in _do
    open_file_success = self.open_file(filepath)  # _do is called inside event_loop, so we can block here.
  File "./lsp-bridge/lsp_bridge.py", line 538, in open_file
    project_path = get_project_path(filepath)
  File "/common/homes/students/ughlu_gleissner/lsp-bridge/core/utils.py", line 384, in get_project_path
    if get_command_result("git rev-parse --is-inside-work-tree", dir_path) == "true":
  File "/common/homes/students/ughlu_gleissner/lsp-bridge/core/utils.py", line 285, in get_command_result
    encoding="utf-8", errors="replace")
TypeError: __init__() got an unexpected keyword argument 'text'

This error is because the Python versoin in your server is too older, I have commit 29cc7a0 patch that make get_command_result works with Python below 3.7

@Moerliy You can update to newest version and try again.

@Moerliy
Copy link
Contributor Author

Moerliy commented Nov 13, 2023

@manateelazycat seems to work now, but using the numerical IPv4 is required otherwise it will not work.
You're right the python3 version we use at work is quite old.

I only checked it with one project that uses typescript tho. The language server should not make any difference but I will have a look at some other projects tomorrow to make sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants