conda.el icon indicating copy to clipboard operation
conda.el copied to clipboard

Tramp support?

Open mtekman opened this issue 5 years ago • 19 comments

Is there any interest in getting this to work on remote machines via TRAMP?

I find that "conda-env-list" does not produce any output

mtekman avatar May 20 '19 09:05 mtekman

@mtekman that's certainly an interesting idea, although I'm personally not sure what you would want to use it for remotely. When you activate a conda environment remotely, all of the functionality you might get from it (e.g. interactive Python REPL, documentation & IDE support) would have to be sent to / from the server, which doesn't sound very appealing to me.

Can you share some more about your use case, so I can understand better what functionality you'd like to have over the remote connection?

necaris avatar May 25 '19 19:05 necaris

@necaris When debugging an R script via ESS-mode (which works in TRAMP) the mode defaults to using the default path, which does not contain the conda packages I need to properly debug the script.

mtekman avatar May 28 '19 13:05 mtekman

@mtekman thank you for the clarification! I don't know ESS personally, but from a quick search it seems like when running ESS over Tramp, Emacs is connecting to a remote R process via SSH, rather than running shell commands on the remote server?

necaris avatar May 28 '19 15:05 necaris

@necaris By my understanding, it spawns an R process over SSH on the remote server, and all local instructions are transferred to and then executed on the remote server, and then the results are transported back to the local machine. Controlling what conda environment the ~~local~~ remote machine uses is the problem for me.

Edit: Corrected machine

mtekman avatar May 28 '19 20:05 mtekman

@mtekman now I'm confused. Do you need to have the conda environments on the remote machine, where the script is running, or the local machine where you might want to debug the results?

The way it works right now, using the appropriate conda environment locally should be as easy as calling conda-env-activate. j

However, I'm not sure how to start telling Emacs / ESS-mode how to activate the conda environment on the remote machine...

necaris avatar Jun 07 '19 18:06 necaris

Apologies, on the remote machine.

mtekman avatar Jun 19 '19 07:06 mtekman

Interestered for this feature too. Imo, the conda env must be on the remote machine. You connect to it with Tramp and you should be able to conda-env-list all envs on the machine.

It could be a great improvment :)

Qwarctick avatar Jun 30 '19 20:06 Qwarctick

Also interested in this. I'm envisioning activating a conda env on a remote machine so that I can use a remote python language server with lsp-mode, and that path variables would be correct.

jsigman avatar May 29 '20 17:05 jsigman

I was poking through the source a few days ago, and one issue is that the current package looks for a specific conda installation directory:

(defcustom conda-env-home-directory "~/anaconda"
  "Location of the directory containing the environments directory."
  :type 'directory
  :group 'conda)

Given that different remote machines are configured differently, there is no catch-all solution to setting this for hosts, unless the user sets this for all their hosts:

(defcustom conda-env-home-directory 
  '((home . "~/anaconda") (remote1 . "~/miniconda") (remote2 . "~/miniconda3"))
  "Alist of locations containing the environments directory."
  :type 'alist
  :group 'conda)

Either the package looks in all these locations for an envs folder (when TRAMP is active), or it maps very specifically to the hostname or ip which should appear in the above list.

mtekman avatar May 29 '20 17:05 mtekman

@jsigman just for clarification, you're saying you'd like to activate the conda environment and run the language server all on the remote machine, and communicate with it from your local Emacs? This seems similar to @mtekman's use case of wanting to run exclusively remote commands -- so we're basically saying that all of the "conda activate" (etc) commands we need to run have to run on the remote end of a specific TRAMP connection?

I'm wondering if we can use something like the solution described here to activate an environment when the TRAMP connection is established, and otherwise use builtin Emacs methods for running commands within the (conda-activated) TRAMP session.

necaris avatar May 31 '20 18:05 necaris

lsp and the python-shell-interpreter already work with tramp when conda-env-current-dir is set manually, with

;; remove "/ssh:host:" from conda dir
(setq conda-tramp-path (replace-regexp-in-string ".*:" ""
                                           (format "%s/bin" conda-env-current-dir)))
(add-to-list 'tramp-remote-path conda-tramp-path)
(add-to-list 'tramp-remote-path 'tramp-own-remote-path) ;; for some strange emacs reason this has to be added, otherwise tramp-remote-path is ignored

(tramp-cleanup-current-connection probably has to be called for the tramp path to be applied)

So the functionality, that would have to be added, is:

  • change conda-env-list to work differently when on remote host: (conda-env-candidates-from-dir "/ssh:host:~/miniconda3/envs") already works, conda-env-default-location would have to be changed
  • change conda-env-activate to be able to select a remote environment (changing the conda-env-default-location function should be enough) and execute the code at the top to adapt the tramp path
  • undo the changes to tramp-remote-path when conda-env-deactivate is called

I don't know about all the other functionality though, e.g., eshell ...

f-kretschmer avatar May 31 '20 22:05 f-kretschmer

@necaris You are understanding correctly, and I would love to try to help with this. For me, it's about getting lsp-mode to work on a restrictive server. I might try to catch up on this package some more this weekend.

jsigman avatar Jun 01 '20 13:06 jsigman

@fcupo thank you for doing all that research! So it looks like we need to:

  • find a nice user experience to set the conda-env-default-location, e.g. perhaps setting an alist of known remote hosts as @mtekman suggested
    • (please bear in mind my concern here is making this convenient while not making the common case of local environments any less convenient)
  • update the conda-env-default-location to return the tramp-enabled path if that's appropriate
  • update the activation and deactivation functions to know about tramp paths and execute the appropriate setup / teardown code when they encounter one

necaris avatar Jun 01 '20 16:06 necaris

Anyone still interested in helping with this?

necaris avatar Jun 28 '22 18:06 necaris

@necaris Looks like it's been a minute since there was some discussion on this, but I'm chiming in to say I have the exact same use case as @jsigman, and came across this thread looking for solutions. No promises at the moment, but assuming I find some time and have strong enough emacs-fu I'd love to help out

renzmann avatar Sep 09 '22 00:09 renzmann

@renzmann let me know if you need any help!

necaris avatar Sep 11 '22 17:09 necaris

Hey @necaris! Before I tried to change up too many things I thought I'd take down some notes for potential discussion.

I think the main barrier to TRAMP right now would be the caching mechanism, like when we poll for conda--executable-path https://github.com/necaris/conda.el/blob/cb9544e8f7d6c642b7fd8c1ecc2cf4fc7370c352/conda.el#L116-L122

This setup assumes a pretty different working model than how I and some of the users above would be using conda, which would have a different executable path to conda for each connection. So I might have a dozen or so different conda executables I'm working with, depending on which machine the current buffer is located on. I think a fair assumption here, though, would be that an executable path is unique to each connection, so we could maybe take an alist of TRAMP prefixes and cache those:

;; Made up executable paths
(setq conda--executable-path-alist
      '(("/ssh:my-host:" . "/usr/local/bin/conda")
        ("/ssh:another-host:" . "~/.conda/bin/conda")
        (nil . "/opt/conda/bin/conda"))

I think we can reliably get the different hostnames via (file-remote-p default-directory), but I'm not sure if there are any footguns hidden in there about the way file-remote-p or default-directory work. We also just need to add a 'remote to how we find the conda/mamba executable:

(defun conda--get-executable-path ()
  ;; caching steps omitted for brevity
  (cond
   ((executable-find "conda" 'remote))
   ((executable-find "mamba" 'remote))))

With that step out of the way, I think it's then a matter of patching variables with the correct connection/host component to get the downstream components working, as mentioned above.

renzmann avatar Sep 16 '22 12:09 renzmann

@renzmann that all seems sensible to me! The main concern I have is that it shouldn't require any extra work for the common case of a local environment :smile:

necaris avatar Sep 18 '22 01:09 necaris