From: Michael Albinus Date: Tue, 7 May 2024 07:56:05 +0000 (+0200) Subject: Add Tramp method "apptainer" X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=bef5b80e944ed5825be81a72bf5b788378c98572;p=emacs.git Add Tramp method "apptainer" * doc/misc/tramp.texi (Top, Configuration): Add "Optional methods". (Optional methods): New section. (Inline methods) : These are optional methods. (Inline methods) : Add. * etc/NEWS: New Tramp method "apptainer". Some Tramp methods are optional. Fix typos. * lisp/net/tramp-androidsu.el (tramp-enable-androidsu-method): New defun. Call it when `system-type' is `android'. * lisp/net/tramp-container.el (tramp-apptainer-program): New defcustom. (tramp-apptainer-method): New defconst. (tramp-apptainer--completion-function) (tramp-enable-toolbox-method, tramp-enable-flatpak-method) (tramp-enable-apptainer-method): New defuns. * lisp/net/tramp.el (tramp-enable-method): New defun. * test/lisp/net/tramp-tests.el (tramp--test-container-p): Add "apptainer". (tramp--test-supports-processes-p): Extend function. (cherry picked from commit 4808c63d43f529f41aac2f2bb14df7ab8f882440) --- diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index febc266c249..aa628e55f82 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -119,6 +119,7 @@ Installing @value{tramp} with your Emacs Configuring @value{tramp} for use +* Optional methods:: Optional methods which must be enabled first. * Connection types:: Types of connections to remote hosts. * Inline methods:: Inline methods. * External methods:: External methods. @@ -685,6 +686,7 @@ to non-@code{nil}, @xref{Directory Variables, , , emacs}. @menu +* Optional methods:: Optional methods which must be enabled first. * Connection types:: Types of connections to remote hosts. * Inline methods:: Inline methods. * External methods:: External methods. @@ -718,6 +720,30 @@ on the remote host. @end menu +@node Optional methods +@section Optional methods which must be enabled first +@cindex optional methods + +Not all methods are enabled by default after loading @value{tramp}. +Some of them don't work on the local host. Some of them are optional, +and must be enabled if it is intended to use them. For all methods +described in this manual, it is indicated when the method is optional. + +@deffn Command tramp-enable-method method +This command enables the optional method @var{method}, a string. The +command can be invoked interactively like @kbd{M-x tramp-enable-method +@key{RET} toolbox @key{RET}}, with @option{toolbox} being an optional +method. +@end deffn + +If you want to enable an optional method permanently, add something +like this to your @file{.emacs} file: + +@lisp +(with-eval-after-load 'tramp (tramp-enable-method "toolbox")) +@end lisp + + @node Connection types @section Types of connections to remote hosts @cindex connection types, overview @@ -834,6 +860,9 @@ equivalent @option{androidsu} method is provided for that system with workarounds for its many idiosyncrasies, with the exception that multi-hops are unsupported. +This is an optional method, @ref{Optional methods}. It is enabled by +default on @code{android} systems only. + @item @option{sudo} @cindex method @option{sudo} @cindex @option{sudo} method @@ -960,7 +989,8 @@ a container's name or ID, as returned by @samp{toolbox list -c}. Without a host name, the default Toolbox container for the host will be used. -This method does not support user names. +This is an optional method, @ref{Optional methods}. It does not +support user names. @item @option{flatpak} @cindex method @option{flatpak} @@ -970,7 +1000,18 @@ Integration of Flatpak sandboxes. The host name may be either an application ID, a sandbox instance ID, or a PID, as returned by @samp{flatpak ps}. -This method does not support user names. +This is an optional method, @ref{Optional methods}. It does not +support user names. + +@item @option{apptainer} +@cindex method @option{apptainer} +@cindex @option{apptainer} method + +Integration of Apptainer instances. The host name is the instance +name, as returned by @samp{apptainer instance list}. + +This is an optional method, @ref{Optional methods}. It does not +support user names. @end table diff --git a/etc/NEWS b/etc/NEWS index 16cb8c74147..bcb6ea5b46f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -150,7 +150,7 @@ This user option controls outline visibility in the output buffer of *** 'C-h m' ('describe-mode') uses outlining by default. Set 'describe-mode-outline' to nil to get back the old behavior. -** Outline Mode +** Outline mode +++ *** 'outline-minor-mode' is supported in tree-sitter major modes. @@ -386,7 +386,7 @@ them. ** New optional argument for modifying directory-local variables. The commands 'add-dir-local-variable', 'delete-dir-local-variable' and 'copy-file-locals-to-dir-locals' now take an optional prefix argument, -to enter the file you want to modify. +to enter the file name you want to modify. ** Emacs Server and Client @@ -1149,7 +1149,12 @@ mode line. 'header' will display in the header line; ** Tramp +++ -*** New connection method "androidsu". +*** Tramp methods can be optional. +An optional connection method is not enabled by default. The user must +enable it explicitly by the 'tramp-enable-method' command. + ++++ +*** New optional connection method "androidsu". This provides access to system files with elevated privileges granted by the idiosyncratic 'su' implementations and system utilities customary on Android. @@ -1159,9 +1164,9 @@ Android. These are the external methods counterparts of "docker" and "podman". +++ -*** New connection methods "toolbox" and "flatpak". -They allow accessing system containers provided by Toolbox or -sandboxes provided by Flatpak. +*** New optional connection methods "toolbox", "flatpak" and "apptainer". +They allow accessing system containers provided by Toolbox, sandboxes +provided by Flatpak, or instances managed by Apptainer. +++ *** Connection method "kubernetes" supports now optional container name. @@ -1236,7 +1241,7 @@ input, as the case may be. *** EWW text input fields and areas are now fields. In consequence, movement commands and OS input method features now recognize and confine their activities to the text input field around -point. See also (elisp)Fields. +point. See also the Info node "(elisp) Fields". +++ *** 'eww-open-file' can now display the file in a new buffer. @@ -1396,7 +1401,7 @@ the margin indicator. *** New user option 'flymake-autoresize-margins'. If non-nil, Flymake will resize the margins when 'flymake-mode' is turned on or off. -Only relevant if `flymake-indicator-type` is set to `margins`. +Only relevant if 'flymake-indicator-type' is set to 'margins'. +++ *** New user option 'flymake-margin-indicator-position'. @@ -1482,12 +1487,12 @@ when using the ':vc' keyword. ** Gnus +++ -*** New back end 'nnfeed'. -This allows back end developers to easily create new back ends for web -feeds, as inheriting back ends of 'nnfeed'. +*** New backend 'nnfeed'. +This allows backend developers to easily create new backends for web +feeds, as inheriting backends of 'nnfeed'. +++ -*** New back end 'nnatom'. +*** New backend 'nnatom'. This allow users to add Atom Syndication Format feeds to Gnus as servers. @@ -1714,7 +1719,8 @@ macros with many lines, such as from 'kmacro-edit-lossage'. The user option 'proced-auto-update-flag' can now be set to 2 additional values, which control automatic updates of Proced buffers that are not displayed in some window. -** Kmacro Menu Mode + +** Kmacro Menu mode +++ *** New mode 'kmacro-menu-mode' and new command 'list-keyboard-macros'. @@ -1774,7 +1780,7 @@ options of GNU 'ls'. +++ *** New user option 'widget-skip-inactive'. If non-nil, moving point forward or backward between widgets by typing -TAB or S-TAB skips over inactive widgets. The default value is nil. +'TAB' or 'S-TAB' skips over inactive widgets. The default value is nil. ** Miscellaneous @@ -1790,7 +1796,7 @@ Now, calling '(thing-at-point 'url)' when point is on a bug reference will return the URL for that bug. +++ -*** New user option 'rcirc-log-time-format' +*** New user option 'rcirc-log-time-format'. This allows for rcirc logs to use a custom timestamp format, than the chat buffers use by default. @@ -1926,9 +1932,9 @@ various subparts (when 'interactive-form', 'documentation', and ** 'define-globalized-minor-mode' requires that modes use 'run-mode-hooks'. Minor modes defined with 'define-globalized-minor-mode', such as 'global-font-lock-mode', will not be enabled any more in those buffers -whose major modes fails to use 'run-mode-hooks'. Major modes defined -with 'define-derived-mode' are not affected. `run-mode-hooks` has been the -recommended way to run major mode hooks since Emacs-22. +whose major modes fail to use 'run-mode-hooks'. Major modes defined +with 'define-derived-mode' are not affected. 'run-mode-hooks' has been the +recommended way to run major mode hooks since Emacs 22. --- ** Old derived.el functions removed. @@ -2100,8 +2106,9 @@ arguments and its return type using the 'declare' macro. 'interpreted-function' is the new type used for interpreted functions, and 'closure' is the common parent type of 'interpreted-function' and 'byte-code-function'. -Those new types come with the associated new predicates -'closurep' and `interpreted-function-p' as well as a new constructor + +Those new types come with the associated new predicates 'closurep' and +`interpreted-function-p' as well as a new constructor 'make-interpreted-closure'. ** New function 'help-fns-function-name'. @@ -2161,9 +2168,9 @@ the Info node "(elisp) Handling Errors". +++ ** Tooltips on fringes. It is now possible to provide tooltips on fringes by adding special text -properties 'left-fringe-help' and 'right-fringe-help'. See the "Special -Properties" Info node in the Emacs Lisp Reference Manual for more -details. +properties 'left-fringe-help' and 'right-fringe-help'. See the "(elisp) +Special Properties" Info node in the Emacs Lisp Reference Manual for +more details. +++ ** New 'pop-up-frames' action alist entry for 'display-buffer'. @@ -2750,7 +2757,7 @@ correctly UTF-8 encoded. *** The parser and encoder now accept arbitrarily large integers. Previously, they were limited to the range of signed 64-bit integers. -** New tree-sitter functions and variables for defining and using "things". +** New tree-sitter functions and variables for defining and using "things" +++ *** New variable 'treesit-thing-settings'. @@ -2774,7 +2781,7 @@ accept more kinds of predicates. Lisp programs can now use thing symbols (defined in 'treesit-thing-settings') and any thing definitions for the predicate argument. -** Other tree-sitter function and variable changes. +** Other tree-sitter function and variable changes +++ *** 'treesit-parser-list' now takes additional optional arguments. @@ -2785,13 +2792,11 @@ all parsers, but rather "all parsers with no tags". +++ *** New function 'treesit-parser-changed-ranges'. - This function returns buffer regions that are affected by the last buffer edits. *** New function 'treesit-add-font-lock-rules'. - -This function helps user to add custom font-lock rules to a tree-sitter +This function helps users to add custom font-lock rules to a tree-sitter major mode. --- diff --git a/lisp/net/tramp-androidsu.el b/lisp/net/tramp-androidsu.el index aa7871e6a33..3dcee8e2f8a 100644 --- a/lisp/net/tramp-androidsu.el +++ b/lisp/net/tramp-androidsu.el @@ -77,19 +77,25 @@ may edit files belonging to any and all applications." "Name of the local temporary directory on Android.") ;;;###tramp-autoload -(tramp--with-startup - (add-to-list 'tramp-methods - `(,tramp-androidsu-method - (tramp-login-program "su") - (tramp-login-args (("-") ("%u"))) - (tramp-remote-shell ,tramp-androidsu-local-shell-name) - (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-c")) - (tramp-tmpdir ,tramp-androidsu-local-tmp-directory) - (tramp-connection-timeout 10) - (tramp-shell-name ,tramp-androidsu-local-shell-name))) - (add-to-list 'tramp-default-user-alist - `(,tramp-androidsu-method nil ,tramp-root-id-string))) +(defun tramp-enable-androidsu-method () + "Enable \"androidsu\" method." + (add-to-list 'tramp-methods + `(,tramp-androidsu-method + (tramp-login-program "su") + (tramp-login-args (("-") ("%u"))) + (tramp-remote-shell ,tramp-androidsu-local-shell-name) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-c")) + (tramp-tmpdir ,tramp-androidsu-local-tmp-directory) + (tramp-connection-timeout 10) + (tramp-shell-name ,tramp-androidsu-local-shell-name))) + + (add-to-list 'tramp-default-user-alist + `(,tramp-androidsu-method nil ,tramp-root-id-string))) + +;;;###tramp-autoload +(when (eq system-type 'android) + (tramp-enable-androidsu-method)) (defvar android-use-exec-loader) ; androidfns.c. diff --git a/lisp/net/tramp-container.el b/lisp/net/tramp-container.el index 30639cbeb85..7559f958838 100644 --- a/lisp/net/tramp-container.el +++ b/lisp/net/tramp-container.el @@ -83,6 +83,15 @@ ;; Where: ;; SANDBOX is the running sandbox to connect to. ;; It could be an application ID, an instance ID, or a PID. +;; +;; +;; +;; Open a file on a running Apptainer instance: +;; +;; C-x C-f /apptainer:INSTANCE:/path/to/file +;; +;; Where: +;; INSTANCE is the running instance to connect to. ;;; Code: @@ -142,6 +151,14 @@ If it is nil, the default context will be used." :type '(choice (const "flatpak") (string))) +;;;###tramp-autoload +(defcustom tramp-apptainer-program "apptainer" + "Name of the Apptainer client program." + :group 'tramp + :version "30.1" + :type '(choice (const "apptainer") + (string))) + ;;;###tramp-autoload (defconst tramp-docker-method "docker" "Tramp method name to use to connect to Docker containers.") @@ -172,6 +189,10 @@ This is for out-of-band connections.") (defconst tramp-flatpak-method "flatpak" "Tramp method name to use to connect to Flatpak sandboxes.") +;;;###tramp-autoload +(defconst tramp-apptainer-method "apptainer" + "Tramp method name to use to connect to Apptainer instances.") + ;;;###tramp-autoload (defmacro tramp-skeleton-completion-function (method &rest body) "Skeleton for `tramp-*-completion-function' with multi-hop support. @@ -373,6 +394,28 @@ see its function help for a description of the format." lines))) (mapcar (lambda (name) (list nil name)) (delq nil names))))) +;;;###tramp-autoload +(defun tramp-apptainer--completion-function (method) + "List Apptainer instances available for connection. + +This function is used by `tramp-set-completion-function', please +see its function help for a description of the format." + (tramp-skeleton-completion-function method + (when-let ((raw-list + (shell-command-to-string (concat program " instance list"))) + ;; Ignore header line. + (lines (cdr (split-string raw-list "\n" 'omit))) + (names (mapcar + (lambda (line) + (when (string-match + (rx bol (group (1+ (not space))) + (1+ space) (1+ (not space)) + (1+ space) (1+ (not space))) + line) + (match-string 1 line))) + lines))) + (mapcar (lambda (name) (list nil name)) (delq nil names))))) + ;;;###tramp-autoload (defvar tramp-default-remote-shell) ;; Silence byte compiler. @@ -453,29 +496,9 @@ see its function help for a description of the format." (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-i" "-c")))) - (add-to-list 'tramp-methods - `(,tramp-toolbox-method - (tramp-login-program ,tramp-toolbox-program) - (tramp-login-args (("run") - ("-c" "%h") - ("%l"))) - (tramp-direct-async (,tramp-default-remote-shell "-c")) - (tramp-remote-shell ,tramp-default-remote-shell) - (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-c")))) - - (add-to-list 'tramp-default-host-alist `(,tramp-toolbox-method nil "")) - - (add-to-list 'tramp-methods - `(,tramp-flatpak-method - (tramp-login-program ,tramp-flatpak-program) - (tramp-login-args (("enter") - ("%h") - ("%l"))) - (tramp-direct-async (,tramp-default-remote-shell "-c")) - (tramp-remote-shell ,tramp-default-remote-shell) - (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-c")))) + (add-to-list 'tramp-completion-multi-hop-methods tramp-docker-method) + (add-to-list 'tramp-completion-multi-hop-methods tramp-podman-method) + (add-to-list 'tramp-completion-multi-hop-methods tramp-kubernetes-method) (tramp-set-completion-function tramp-docker-method @@ -495,53 +518,99 @@ see its function help for a description of the format." (tramp-set-completion-function tramp-kubernetes-method - `((tramp-kubernetes--completion-function ,tramp-kubernetes-method))) + `((tramp-kubernetes--completion-function ,tramp-kubernetes-method)))) - (tramp-set-completion-function - tramp-toolbox-method - `((tramp-toolbox--completion-function ,tramp-toolbox-method))) +;;;###tramp-autoload +(defun tramp-enable-toolbox-method () + "Enable connection to Toolbox containers." + (add-to-list 'tramp-methods + `(,tramp-toolbox-method + (tramp-login-program ,tramp-toolbox-program) + (tramp-login-args (("run") + ("-c" "%h") + ("%l"))) + (tramp-direct-async (,tramp-default-remote-shell "-c")) + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-c")))) + + (add-to-list 'tramp-default-host-alist `(,tramp-toolbox-method nil "")) + (add-to-list 'tramp-completion-multi-hop-methods tramp-toolbox-method) + + (tramp-set-completion-function + tramp-toolbox-method + `((tramp-toolbox--completion-function ,tramp-toolbox-method)))) - (tramp-set-completion-function - tramp-flatpak-method - `((tramp-flatpak--completion-function ,tramp-flatpak-method))) +;;;###tramp-autoload +(defun tramp-enable-flatpak-method () + "Enable connection to Flatpak sandboxes." + (add-to-list 'tramp-methods + `(,tramp-flatpak-method + (tramp-login-program ,tramp-flatpak-program) + (tramp-login-args (("enter") + ("%h") + ("%l"))) + (tramp-direct-async (,tramp-default-remote-shell "-c")) + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-c")))) + + (add-to-list 'tramp-completion-multi-hop-methods tramp-flatpak-method) + + (tramp-set-completion-function + tramp-flatpak-method + `((tramp-flatpak--completion-function ,tramp-flatpak-method)))) - (add-to-list 'tramp-completion-multi-hop-methods tramp-docker-method) - (add-to-list 'tramp-completion-multi-hop-methods tramp-podman-method) - (add-to-list 'tramp-completion-multi-hop-methods tramp-kubernetes-method) - (add-to-list 'tramp-completion-multi-hop-methods tramp-toolbox-method) - (add-to-list 'tramp-completion-multi-hop-methods tramp-flatpak-method) - - ;; Default connection-local variables for Tramp. - - (defconst tramp-kubernetes-connection-local-default-variables - '((tramp-config-check . tramp-kubernetes--current-context-data) - ;; This variable will be eval'ed in `tramp-expand-args'. - (tramp-extra-expand-args - . (?a (tramp-kubernetes--container (car tramp-current-connection)) - ?h (tramp-kubernetes--pod (car tramp-current-connection)) - ?x (tramp-kubernetes--context-namespace - (car tramp-current-connection))))) - "Default connection-local variables for remote kubernetes connections.") - - (connection-local-set-profile-variables - 'tramp-kubernetes-connection-local-default-profile - tramp-kubernetes-connection-local-default-variables) - - (connection-local-set-profiles - `(:application tramp :protocol ,tramp-kubernetes-method) - 'tramp-kubernetes-connection-local-default-profile) - - (defconst tramp-flatpak-connection-local-default-variables - `((tramp-remote-path . ,(cons "/app/bin" tramp-remote-path))) - "Default connection-local variables for remote flatpak connections.") - - (connection-local-set-profile-variables - 'tramp-flatpak-connection-local-default-profile - tramp-flatpak-connection-local-default-variables) - - (connection-local-set-profiles - `(:application tramp :protocol ,tramp-flatpak-method) - 'tramp-flatpak-connection-local-default-profile)) +;;;###tramp-autoload +(defun tramp-enable-apptainer-method () + "Enable connection to Apptainer instances." + (add-to-list 'tramp-methods + `(,tramp-apptainer-method + (tramp-login-program ,tramp-apptainer-program) + (tramp-login-args (("shell") + ("instance://%h") + ("%h"))) ; Needed for multi-hop check. + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-c")))) + + (add-to-list 'tramp-completion-multi-hop-methods tramp-apptainer-method) + + (tramp-set-completion-function + tramp-apptainer-method + `((tramp-apptainer--completion-function ,tramp-apptainer-method)))) + +;; Default connection-local variables for Tramp. + +(defconst tramp-kubernetes-connection-local-default-variables + '((tramp-config-check . tramp-kubernetes--current-context-data) + ;; This variable will be eval'ed in `tramp-expand-args'. + (tramp-extra-expand-args + . (?a (tramp-kubernetes--container (car tramp-current-connection)) + ?h (tramp-kubernetes--pod (car tramp-current-connection)) + ?x (tramp-kubernetes--context-namespace + (car tramp-current-connection))))) + "Default connection-local variables for remote kubernetes connections.") + +(connection-local-set-profile-variables + 'tramp-kubernetes-connection-local-default-profile + tramp-kubernetes-connection-local-default-variables) + +(connection-local-set-profiles + `(:application tramp :protocol ,tramp-kubernetes-method) + 'tramp-kubernetes-connection-local-default-profile) + +(defconst tramp-flatpak-connection-local-default-variables + `((tramp-remote-path . ,(cons "/app/bin" tramp-remote-path))) + "Default connection-local variables for remote flatpak connections.") + +(connection-local-set-profile-variables + 'tramp-flatpak-connection-local-default-profile + tramp-flatpak-connection-local-default-variables) + +(connection-local-set-profiles + `(:application tramp :protocol ,tramp-flatpak-method) + 'tramp-flatpak-connection-local-default-profile) (add-hook 'tramp-unload-hook (lambda () diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 534839a0064..6b002366c17 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1460,6 +1460,15 @@ calling HANDLER.") ;;; Internal functions which must come first: +(defun tramp-enable-method (method) + "Enable optional METHOD if possible." + (interactive "Mmethod: ") + (when-let (((not (assoc method tramp-methods))) + (fn (intern (format "tramp-enable-%s-method" method))) + ((functionp fn))) + (funcall fn) + (message "Tramp method \"%s\" enabled" method))) + ;; Conversion functions between external representation and ;; internal data structure. Convenience functions for internal ;; data structure. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index a03502bb9a5..88d6c13331d 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -6755,7 +6755,7 @@ This is used in tests which we don't want to tag "Check, whether a container method is used. This does not support some special file names." (string-match-p - (rx bol (| "docker" "podman")) + (rx bol (| "docker" "podman" "apptainer")) (file-remote-p ert-remote-temporary-file-directory 'method))) (defun tramp--test-container-oob-p () @@ -6924,8 +6924,14 @@ This requires restrictions of file name syntax." (defun tramp--test-supports-processes-p () "Return whether the method under test supports external processes." - (and (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p)) - (not (tramp--test-crypt-p)))) + ;; We use it to enable/disable tests in a given test run, for + ;; example for remote processes on MS Windows. + (if (tramp-connection-property-p + tramp-test-vec "tramp--test-supports-processes-p") + (tramp-get-connection-property + tramp-test-vec "tramp--test-supports-processes-p") + (and (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p)) + (not (tramp--test-crypt-p))))) (defun tramp--test-supports-set-file-modes-p () "Return whether the method under test supports setting file modes."