forked from fejfighter/toolbox-tramp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoolbox-tramp.el
151 lines (120 loc) · 5.6 KB
/
toolbox-tramp.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
;;; toolbox-tramp.el --- tramp connection to toolbx containers -*- lexical-binding: t; -*-
;; Copyright (C) 2022 Jeff Walsh
;; Author: Jeff Walsh <[email protected]>
;; Keywords: convenience, tools
;; Version: 0.5.0
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Connect to podman's toolbox containers, shamelessly influenced
;; by/stolen from docker-tramp.el, just specialized/re-written for
;; toolbox
;;; Code:
(require 'tramp)
(eval-when-compile (require 'subr-x))
(defgroup toolbox-tramp nil
"TRAMP integration for toolbox containers."
:prefix "toolbox-tramp-"
:group 'applications
:link '(url-link :tag "Github" "https://github.com/fejfighter/toolbox-tramp")
:link '(emacs-commentary-link :tag "Commentary" "toolbox-tramp"))
(defconst toolbox-tramp-executable "podman")
(defconst toolbox-tramp-podman-args '(("exec" "-it") ("-u" "%u") ("%h") ("%l")))
(defconst toolbox-tramp-podman-list `(,toolbox-tramp-executable "container" "list" "--format={{.Names}}"))
(defconst toolbox-tramp-podman-label-filter '("-f=label=com.github.containers.toolbox=true"))
(defun toolbox-tramp-toolbox-containers (&optional ignored)
"Return known running toolbox containers."
(let* ((args . ((append toolbox-tramp-podman-list
toolbox-tramp-podman-label-filter))))
(apply 'process-lines args)))
(defun toolbox-tramp-toolbox-containers-completion (&optional ignored)
"Return known running toolbox containers for tramp completion."
(mapcar (lambda (x) (list nil x))
(toolbox-tramp-toolbox-containers)))
(defun toolbox-tramp-stopped-toolbox-containers (&optional ignored)
"Return known toolbox stopped containers."
(let* ((args . ((append toolbox-tramp-podman-list
toolbox-tramp-podman-label-filter
'("-f=status=exited"
"-f=status=created"
"-f=status=paused")))))
(apply 'process-lines args)))
(defun toolbox-tramp-all-containers (&optional ignored)
"Return known running podman containers."
(mapcar (lambda (x) (list nil x))
(apply 'process-lines toolbox-tramp-podman-list)))
(defun toolbox-tramp-start-toolbox (container)
"Start a toolbox container for later connection."
(interactive
(list (completing-read "Which Container" (toolbox-tramp-stopped-toolbox-containers))))
(let ((args . ((append `(,toolbox-tramp-executable "container" "start")))))
(apply 'call-process (append (list (car args) nil nil nil) (cdr args) (list container)))))
(defun toolbox-tramp--path-for-buffer (path container)
(let* ((toolbox . ((concat "/toolbox:" container ":")))
(full-path . ((expand-file-name path)))
(localised-path . ((if (file-remote-p full-path)
(file-remote-p full-path 'localname)
full-path))))
(concat toolbox localised-path)))
(defun toolbox-tramp-reopen-file-in-toolbox (buffer container)
"Reopen a BUFFER inside a toolbox CONTAINER.
This also allows for changing current container."
(interactive (list
(read-buffer "Buffer: " (current-buffer) t)
(completing-read "Which Container" (toolbox-tramp-toolbox-containers))))
(find-alternate-file (toolbox-tramp--path-for-buffer
(buffer-file-name (get-buffer buffer))
container)))
;;;###autoload
(defun toolbox-tramp-login-args ()
"returns the correct login args for the connection type"
toolbox-tramp-podman-args)
;;;###autoload
(defconst podman-tramp-completion-function-alist
'((toolbox-tramp-all-containers ""))
"Default list of (FUNCTION FILE) pairs to be examined for podman method.")
;;;###autoload
(defconst toolbox-tramp-completion-function-alist
'((toolbox-tramp-toolbox-containers-completion ""))
"Default list of (FUNCTION FILE) pairs to be examined for toolbox method.")
;;;###autoload
(defconst toolbox-tramp-method "toolbox"
"Method to connect toolbox containers.")
;;;###autoload
(defun toolbox-tramp-add-method ()
"Add toolbox tramp method."
(add-to-list 'tramp-methods
`(,toolbox-tramp-method
(tramp-login-program ,toolbox-tramp-executable)
(tramp-login-args ,(toolbox-tramp-login-args))
(tramp-remote-shell ,tramp-default-remote-shell)
(tramp-remote-shell-login ("-l"))
(tramp-remote-shell-args ("-i -c")))))
(defconst toolbox-tramp-default-prefix "fedora-toolbox-")
(defvar toolbox-tramp-default-container
(with-temp-buffer
(insert-file-contents
(if-let (file-exists-p "/run/host/etc/os-release") "/run/host/etc/os-release" "/etc/os-release"))
(keep-lines "VERSION_ID" (point-min) (point-max))
(concat toolbox-tramp-default-prefix (when (string-match "VERSION_ID=\\(.*\\)" (buffer-string))
(match-string 1 (buffer-string))))))
(defvar toolbox-tramp-default-user
(user-login-name))
(add-to-list 'tramp-default-host-alist `(,toolbox-tramp-method ,toolbox-tramp-default-user ,toolbox-tramp-default-container))
(add-to-list 'tramp-default-user-alist `("\\`toolbox\\'" nil ,toolbox-tramp-default-user))
;;;###autoload
(eval-after-load 'tramp
'(progn
(toolbox-tramp-add-method)
(tramp-set-completion-function
toolbox-tramp-method
toolbox-tramp-completion-function-alist)))
(provide 'toolbox-tramp)