Tramp: Support different proxies for the same destination

* 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)
This commit is contained in:
Michael Albinus 2024-11-09 10:29:42 +01:00
parent 200214ca68
commit 6cde51f1bb
4 changed files with 81 additions and 27 deletions

View 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

View file

@ -183,8 +183,8 @@ Input methods are now implemented for Haudenosaunee languages in the
Northern Iroquoian language family: 'mohawk-postfix' (Mohawk
[Kanienkéha / Onkwehonwehnéha]), 'oneida-postfix' (Oneida [Onʌyota:ká:
/ Ukwehuwehnéha]), 'cayuga-postfix' (Cayuga [Gayogo̱ho:nǫhnéha:ˀ]),
'onondaga-postfix (Onondaga [[Onųdaʔgegáʔ]), and `seneca-postfix'
[Onödowága:]). Additionally, there is a general-purpose
'onondaga-postfix' (Onondaga [Onųdaʔgegáʔ]), and 'seneca-postfix'
(Seneca [Onödowága:]). Additionally, there is a general-purpose
'haudenosaunee-postfix' input method to facilitate writing in the
orthographies of the five languages simultaneously.
@ -267,7 +267,7 @@ It removes all the buttons in the specified region.
This command scrolls the screen so that only the current prompt is
visible, optionally erasing all the previous input/output as well.
Previously, the Eshell built-in command 'eshell/clear' supported this
(e.g. to call it via 'M-x'), but this new command behaves more
(e.g., to call it via 'M-x'), but this new command behaves more
consistently if you have a partially-typed command at the Eshell prompt.
---
@ -486,6 +486,19 @@ The host name for Kubernetes connections can be of kind
used. This overrides the setting in 'tramp-kubernetes-namespace', if
any.
+++
*** Different proxies for the same destination host name can be specified.
A typical example are docker containers, which run on different hosts
under the same docker name. When the user option
'tramp-show-ad-hoc-proxies' is non-nil, such ad-hoc multi-hop file names
can be used in parallel. Example: on both remote hosts "host1" and
"host2" there is a docker container "name", respectively:
/ssh:user1@host1|docker:name:
/ssh:user2@host2|docker:name:
This feature is experimental.
** Diff
---
@ -562,17 +575,17 @@ be set as a connection-local variable.
---
*** New user option 'dired-hide-details-hide-absolute-location'.
When dired's 'dired-hide-details-mode' is enabled, also hide the
When Dired's 'dired-hide-details-mode' is enabled, also hide the
'default-directory' absolute location, typically displayed as the first
line in a dired buffer.
line in a Dired buffer.
With dired-hide-details-hide-absolute-location:
With 'dired-hide-details-hide-absolute-location':
project: (100 GiB available)
project: (100 GiB available)
Without dired-hide-details-hide-absolute-location:
Without 'dired-hide-details-hide-absolute-location':
/absolute/path/to/my/important/project: (100 GiB available)
/absolute/path/to/my/important/project: (100 GiB available)
** Grep
@ -622,7 +635,7 @@ The hardcoded '^' shortcut gets you back to the previous menu.
---
*** New user option 'tmm-shortcut-inside-entry'.
When non-nil, highlight the character shortcut in the menu entry's
string instead of preprending it and `tmm-mid-prompt' to said entry.
string instead of preprending it and 'tmm-mid-prompt' to said entry.
** Foldout
@ -655,8 +668,8 @@ of seconds. Crossfading can be toggled using the command
*** New user option 'vc-allow-rewriting-published-history'.
Some VCS commands can change your copy of published change history
without warning. In VC we try to detect before that happens, and stop.
You can customize this variable to permit rewriting history
even though Emacs thinks it is dangerous.
You can customize this option to permit rewriting history even though
Emacs thinks it is dangerous.
---
*** 'vc-clone' is now an interactive command.
@ -846,7 +859,7 @@ variable 'w32-inhibit-dwrite' to t. Also see 'w32-dwrite-available' and
'w32-dwrite-reinit' to check availability and to configure the
DirectWrite rendering parameters.
To show color Emoji in Emacs, customize the default fontset to use a
To show color Emojis in Emacs, customize the default fontset to use a
color Emoji font installed on your system for the 'emoji' script.
+++

View file

@ -118,11 +118,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.

View file

@ -1886,7 +1886,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)
@ -4177,7 +4178,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
@ -4271,7 +4272,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
@ -4912,21 +4913,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))
;; `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)