GithubHelp home page GithubHelp logo

Tramp support? about conda.el HOT 19 OPEN

necaris avatar necaris commented on August 20, 2024 4
Tramp support?

from conda.el.

Comments (19)

Qwarctick avatar Qwarctick commented on August 20, 2024 8

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 :)

from conda.el.

jsigman avatar jsigman commented on August 20, 2024 5

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.

from conda.el.

claytharrison avatar claytharrison commented on August 20, 2024 4

Hi, I'm an elisp beginner so unfortunately this isn't much of a contribution towards a robust solution of this issue in the package, but I wanted to put my workaround here for anyone else who happens to come here needing one. (with thanks to @f-kretschmer for their comment here a few years back)

I haven't tested this extensively with eglot, etc, my only use-case is to be able to execute org-mode src blocks in the correct remote environment, and it works for that. I think it's using the remote language server for eglot too but I'm not entirely sure to easily tell if that's the case. Maybe it will work for the other stuff too.

(setq remote-conda-anaconda-home-list
      '(("remote01" "/ssh:me@remote01:/home/me/conda/special_conda")
        ("remote02" "/ssh:me@remote02:/home/me/miniforge3")))

(setq remote-conda-env-home-directory-list
      '(("remote01" "/ssh:me@remote01:/home/me/conda/special_conda")
        ("remote02" "/ssh:me@remote02:/home/me/miniforge3")))

(setq remote-conda-env-subdirectory-list
      '(("remote01" "envs")
        ("remote02" "envs")))

(defun conda-tramp-activate (conda-env)
        "Activate a conda environment on a remote host."
        (interactive "sConda environment: ")
        (let ((hostname (file-remote-p default-directory 'host)))
                (setq conda-anaconda-home (cadr (assoc hostname remote-conda-anaconda-home-list)))
                (setq conda-env-home-directory (cadr (assoc hostname remote-conda-env-home-directory-list)))
                (setq conda-env-subdirectory (cadr (assoc hostname remote-conda-env-subdirectory-list)))

                ;; check if dir conda-env exists in conda-env-home-directory/conda-env-subdirectory
                (if (not (file-exists-p (f-join conda-env-home-directory conda-env-subdirectory conda-env)))
                        (error "Conda environment %s does not exist on remote host %s" conda-env hostname))

                (setq conda-env-current-path (f-join conda-anaconda-home conda-env-subdirectory conda-env))
                (setq conda-tramp-path (replace-regexp-in-string ".*:" ""
                                                        (format "%s/bin" conda-env-current-path)))
                (add-to-list 'tramp-remote-path 'tramp-own-remote-path) ;; need to do this BEFORE the next line or else python won't find the right remote env and will just use the base env
                (add-to-list 'tramp-remote-path conda-tramp-path)
                (tramp-cleanup-this-connection))
)

from conda.el.

f-kretschmer avatar f-kretschmer commented on August 20, 2024 2

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 ...

from conda.el.

jsigman avatar jsigman commented on August 20, 2024 1

@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.

from conda.el.

necaris avatar necaris commented on August 20, 2024 1

@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

from conda.el.

necaris avatar necaris commented on August 20, 2024 1

Anyone still interested in helping with this?

from conda.el.

renzmann avatar renzmann commented on August 20, 2024 1

@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

from conda.el.

necaris avatar necaris commented on August 20, 2024

@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?

from conda.el.

mtekman avatar mtekman commented on August 20, 2024

@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.

from conda.el.

necaris avatar necaris commented on August 20, 2024

@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?

from conda.el.

mtekman avatar mtekman commented on August 20, 2024

@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

from conda.el.

necaris avatar necaris commented on August 20, 2024

@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...

from conda.el.

mtekman avatar mtekman commented on August 20, 2024

Apologies, on the remote machine.

from conda.el.

mtekman avatar mtekman commented on August 20, 2024

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.

from conda.el.

necaris avatar necaris commented on August 20, 2024

@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.

from conda.el.

necaris avatar necaris commented on August 20, 2024

@renzmann let me know if you need any help!

from conda.el.

renzmann avatar renzmann commented on August 20, 2024

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

conda.el/conda.el

Lines 116 to 122 in cb9544e

(defvar conda--executable-path nil
"Cached copy of full path to Conda binary. Set for the lifetime of the process.")
(defun conda--get-executable-path ()
"Return full path to Conda binary, or throw an error if it can't be found. Cached for the lifetime of the process."
(if (not (eq conda--executable-path nil))
conda--executable-path

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.

from conda.el.

necaris avatar necaris commented on August 20, 2024

@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 😄

from conda.el.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.