]> git.eshelyaron.com Git - emacs.git/commitdiff
Tramp: Support different proxies for the same destination
authorMichael Albinus <michael.albinus@gmx.de>
Sat, 9 Nov 2024 09:29:42 +0000 (10:29 +0100)
committerEshel Yaron <me@eshelyaron.com>
Sat, 9 Nov 2024 15:48:37 +0000 (16:48 +0100)
* doc/misc/tramp.texi (Ad-hoc multi-hops): New subsection "Using
different proxies for the same destination".

* etc/NEWS: Tramp supports different proxies for the same
destination host name in parallel.
Fix typos.

* lisp/net/tramp-cmds.el (tramp-cleanup-connection): Fix docstring.

* lisp/net/tramp.el (tramp-make-tramp-file-name): Don't call
`tramp-add-hops' during file name completion.
(tramp-handle-file-name-as-directory)
(tramp-handle-file-name-directory): Use `tramp-cache-undefined'
for an empty `tramp-default-proxies-alist'.
(tramp-add-hops): Extend.  Remove existing entries with same
target and different proxy, if needed.  (Bug#74219)

(cherry picked from commit 6cde51f1bbcfd55fe8d189b045247b9d80dee4ea)

doc/misc/tramp.texi
lisp/net/tramp-cmds.el
lisp/net/tramp.el

index 164cb60fe69fd517804bfb65f2f250fbd401ac41..3526cafad75d0d01d3de182ab18d9908c2203877 100644 (file)
@@ -3914,6 +3914,30 @@ shall be taken, add a proper rule to the user option
 @end lisp
 
 
+@subsection Using different proxies for the same destination
+
+@strong{Note}: This feature is experimental, don't use it in
+production systems!
+
+Sometimes, it is needed to specify different proxies for the same
+destination host name.  This can happen for the same destination when
+the local host is located in different networks over the time.  This
+can also happen when the remote destination is specified by the remote
+same file name, although different hosts are meant depending on the
+used proxy.  A typical example are docker containers, which run on
+different hosts under the same docker name.
+
+When the user option @code{tramp-show-ad-hoc-proxies} is
+non-@code{nil}, such ad-hoc multi-hop file names can be used in
+parallel.  In the following, on both remote hosts @samp{host1} and
+@samp{host2} there is a docker container @samp{name}, respectively:
+
+@example
+@trampfn{ssh@value{postfixhop}user1@@host1|docker,name,}
+@trampfn{ssh@value{postfixhop}user2@@host2|docker,name,}
+@end example
+
+
 @node Home directories
 @section Expanding @file{~} to home directory
 
index dc3df09ec3b2f6c44b47288574e9d20712ada5a0..d37bb61225586e12370a128d6dabf32652d9ad64 100644 (file)
@@ -116,11 +116,11 @@ Each function is called with the current vector as argument.")
 (defun tramp-cleanup-connection
     (vec &optional keep-debug keep-password keep-processes)
   "Flush all connection related objects.
-This includes password cache, file cache, connection cache,
-buffers, processes.  KEEP-DEBUG non-nil preserves the debug
-buffer.  KEEP-PASSWORD non-nil preserves the password cache.
-KEEP-PROCESSES non-nil preserves the asynchronous processes.
-When called interactively, a Tramp connection has to be selected."
+This includes password cache, file cache, connection cache, buffers,
+processes.  KEEP-DEBUG non-nil preserves the debug and trace buffer.
+KEEP-PASSWORD non-nil preserves the password cache.  KEEP-PROCESSES
+non-nil preserves the asynchronous processes.  When called
+interactively, a Tramp connection has to be selected."
   (declare (completion tramp-active-command-completion-p))
   (interactive
    ;; When interactive, select the Tramp remote identification.
index 55eae7d18500d75bb8c65ee20ba0a79df06b61a3..a7e70de960d742066143db313a53d0546fcb1fac 100644 (file)
@@ -1889,7 +1889,8 @@ expected to be a string, which will be used."
        ;; Assure that the hops are in `tramp-default-proxies-alist'.
        ;; In tramp-archive.el, the slot `hop' is used for the archive
        ;; file name.
-       (unless (string-equal method tramp-archive-method)
+       (unless (or minibuffer-completing-file-name
+                   (string-equal method tramp-archive-method))
          (tramp-add-hops (car args)))))
 
      (t (setq method (nth 0 args)
@@ -4172,7 +4173,7 @@ Let-bind it when necessary.")
   ;; the empty string.  Suppress adding a hop to
   ;; `tramp-default-proxies-alist' due to non-expanded default values.
   (let ((v (tramp-dissect-file-name file t))
-       tramp-default-proxies-alist)
+       (tramp-default-proxies-alist tramp-cache-undefined))
     ;; Run the command on the localname portion only unless we are in
     ;; completion mode.
     (tramp-make-tramp-file-name
@@ -4266,7 +4267,7 @@ Let-bind it when necessary.")
   ;; the remote file name parts.  Suppress adding a hop to
   ;; `tramp-default-proxies-alist' due to non-expanded default values.
   (let ((v (tramp-dissect-file-name file t))
-       tramp-default-proxies-alist)
+       (tramp-default-proxies-alist tramp-cache-undefined))
     ;; Run the command on the localname portion only.  If this returns
     ;; nil, mark also the localname part of `v' as nil.
     (tramp-make-tramp-file-name
@@ -4907,21 +4908,37 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
 
 (defun tramp-add-hops (vec)
   "Add ad-hoc proxy definitions to `tramp-default-proxies-alist'."
-  (when-let ((hops (tramp-file-name-hop vec))
-            (item vec))
+  ;; `tramp-default-proxies-alist' is bound to `tramp-cache-undefined'
+  ;; in `tramp-handle-file-name-as-directory' and
+  ;; `tramp-handle-file-name-directory' suppressing to add a hop.
+  (when-let* (((not (eq        tramp-default-proxies-alist tramp-cache-undefined)))
+             (hops (tramp-file-name-hop vec))
+             (item vec))
     (let (signal-hook-function changed)
       (dolist
          (proxy (reverse (split-string hops tramp-postfix-hop-regexp 'omit)))
        (let* ((host-port (tramp-file-name-host-port item))
+              (host-port (and (stringp host-port)
+                              (rx bol (literal host-port) eol)))
               (user-domain (tramp-file-name-user-domain item))
+              (user-domain (and (stringp user-domain)
+                                (rx bol (literal user-domain) eol)))
               (proxy (concat
                       tramp-prefix-format proxy tramp-postfix-host-format))
               (entry
-               (list (and (stringp host-port)
-                          (rx bol (literal host-port) eol))
-                     (and (stringp user-domain)
-                          (rx bol (literal user-domain) eol))
-                     (propertize proxy 'tramp-ad-hoc t))))
+               (list host-port user-domain (propertize proxy 'tramp-ad-hoc t))))
+         ;; Remove superfluous entries.
+         (when tramp-show-ad-hoc-proxies
+           (dolist (entry1 tramp-default-proxies-alist)
+             (when (and (equal host-port (car entry1))
+                        (equal user-domain (cadr entry1))
+                        (not (equal proxy (caddr entry1))))
+               (tramp-message
+                vec 5 "Remove %S from `tramp-default-proxies-alist'" entry1)
+               (tramp-cleanup-connection
+                vec 'keep-debug 'keep-password 'keep-processes)
+               (setq tramp-default-proxies-alist
+                     (delete entry1 tramp-default-proxies-alist)))))
          ;; Add the hop.
          (unless (member entry tramp-default-proxies-alist)
            (tramp-message vec 5 "Add %S to `tramp-default-proxies-alist'" entry)