Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
10 KiB

  1. ;;; docker-machine.el --- Emacs interface to docker-machine -*- lexical-binding: t -*-
  2. ;; Author: Ben Swift <ben@benswift.me>
  3. ;; This file is NOT part of GNU Emacs.
  4. ;; This program is free software; you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation; either version 3, or (at your option)
  7. ;; any later version.
  8. ;;
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  16. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. ;; Boston, MA 02110-1301, USA.
  18. ;;; Commentary:
  19. ;;; Code:
  20. (require 's)
  21. (require 'dash)
  22. (require 'tablist)
  23. (require 'magit-popup)
  24. (require 'docker-group)
  25. (require 'docker-utils)
  26. (defgroup docker-machine nil
  27. "Docker machine customization group."
  28. :group 'docker)
  29. (defcustom docker-machine-default-sort-key '("Name" . nil)
  30. "Sort key for docker machines.
  31. This should be a cons cell (NAME . FLIP) where
  32. NAME is a string matching one of the column names
  33. and FLIP is a boolean to specify the sort order."
  34. :group 'docker-machine
  35. :type '(cons (choice (const "Name")
  36. (const "Active")
  37. (const "Driver")
  38. (const "State")
  39. (const "URL")
  40. (const "Swarm")
  41. (const "Docker")
  42. (const "Errors"))
  43. (choice (const :tag "Ascending" nil)
  44. (const :tag "Descending" t))))
  45. (defun docker-machine-parse (line)
  46. "Convert a LINE from \"docker machine ls\" to a `tabulated-list-entries' entry."
  47. (let ((data (s-split "\t" line)))
  48. (list (car data) (apply #'vector data))))
  49. (defun docker-machine-entries ()
  50. "Return the docker machines data for `tabulated-list-entries'."
  51. (let* ((fmt "{{.Name}}\\t{{.Active}}\\t{{.DriverName}}\\t{{.State}}\\t{{.URL}}\\t{{.Swarm}}\\t{{.DockerVersion}}\\t{{.Error}}")
  52. (data (docker-machine-run "ls" docker-machine-ls-arguments (format "--format=\"%s\"" fmt)))
  53. (lines (s-split "\n" data t)))
  54. (-map #'docker-machine-parse lines)))
  55. (defun docker-machine-refresh ()
  56. "Refresh the machines list."
  57. (setq tabulated-list-entries (docker-machine-entries)))
  58. (defun docker-machine-read-name ()
  59. "Read a machine name."
  60. (completing-read "Machine: " (-map #'car (docker-machine-entries))))
  61. (defun docker-machine-run (action &rest args)
  62. "Execute \"docker-machine ACTION\" using ARGS."
  63. (let ((command (format "docker-machine %s %s" action (s-join " " (-flatten (-non-nil args))))))
  64. (message command)
  65. (shell-command-to-string command)))
  66. ;;;###autoload
  67. (defun docker-machine-config (name)
  68. "Print the connection config for the machine NAME."
  69. (interactive (list (docker-machine-read-name)))
  70. (docker-machine-run "config" name))
  71. ;;;###autoload
  72. (defun docker-machine-create (name driver)
  73. "Create a machine NAME using DRIVER."
  74. (interactive "sName: \nsDriver: ")
  75. (docker-machine-run "create" name "-d" driver))
  76. ;;;###autoload
  77. (defun docker-machine-env (name)
  78. "Parse and set environment variables from \"docker-machine env NAME\" output."
  79. (interactive (list (docker-machine-read-name)))
  80. (--each-while
  81. (s-lines (docker-machine-run "env" name))
  82. (s-prefix? "export" it)
  83. (docker-machine-env-export it)))
  84. (defun docker-machine-env-export (line)
  85. "Export the env for LINE."
  86. (let ((index (s-index-of "=" line)))
  87. (unless index
  88. (error (format "Cannot find separator in %s" line)))
  89. (setenv (substring line (length "export ") index) (substring line (+ 2 index) -1))))
  90. ;;;###autoload
  91. (defun docker-machine-inspect (name)
  92. "Inspect information about the machine NAME."
  93. (interactive (list (docker-machine-read-name)))
  94. (docker-machine-run "inspect" name))
  95. ;;;###autoload
  96. (defun docker-machine-ip (name)
  97. "Get the IP address of the machine NAME."
  98. (interactive (list (docker-machine-read-name)))
  99. (docker-machine-run "ip" name))
  100. ;;;###autoload
  101. (defun docker-machine-kill (name)
  102. "Kill the machine NAME."
  103. (interactive (list (docker-machine-read-name)))
  104. (docker-machine-run "kill" name))
  105. ;;;###autoload
  106. (defun docker-machine-restart (name)
  107. "Restart the machine NAME."
  108. (interactive (list (docker-machine-read-name) current-prefix-arg))
  109. (docker-machine-run "restart" name))
  110. ;;;###autoload
  111. (defun docker-machine-rm (name &optional force)
  112. "Destroy or uncommand the machine NAME. If FORCE is set, use \"--force\"."
  113. (interactive (list (docker-machine-read-name) current-prefix-arg))
  114. (docker-machine-run "rm" (when force "--force") name))
  115. ;;;###autoload
  116. (defun docker-machine-start (name)
  117. "Start the machine NAME."
  118. (interactive (list (docker-machine-read-name)))
  119. (docker-machine-run "start" name))
  120. ;;;###autoload
  121. (defun docker-machine-status (name)
  122. "Get the status of the machine NAME."
  123. (interactive (list (docker-machine-read-name)))
  124. (docker-machine-run "status" name))
  125. ;;;###autoload
  126. (defun docker-machine-stop (name)
  127. "Stop the machine NAME."
  128. (interactive (list (docker-machine-read-name) current-prefix-arg))
  129. (docker-machine-run "stop" name))
  130. ;;;###autoload
  131. (defun docker-machine-upgrade (name)
  132. "Upgrade the machine NAME to the latest version of Docker."
  133. (interactive (list (docker-machine-read-name)))
  134. (docker-machine-run "upgrade" name))
  135. (defun docker-machine-env-selection ()
  136. "Run \"docker-machine env\" on selected machine."
  137. (interactive)
  138. (let ((marked (docker-utils-get-marked-items-ids)))
  139. (when (/= (length marked) 1)
  140. (error "Can only set environment vars for one machine at a time"))
  141. (docker-machine-env (car marked))
  142. (tablist-revert)))
  143. (defun docker-machine-restart-selection ()
  144. "Run `docker-machine-restart' on the machines selection."
  145. (interactive)
  146. (--each (docker-utils-get-marked-items-ids)
  147. (docker-machine-run "restart" (docker-machine-restart-arguments) it))
  148. (tablist-revert))
  149. (defun docker-machine-rm-selection ()
  150. "Run `docker-machine-rm' on the machines selection."
  151. (interactive)
  152. (--each (docker-utils-get-marked-items-ids)
  153. (docker-machine-run "rm" (docker-machine-rm-arguments) it))
  154. (tablist-revert))
  155. (defun docker-machine-start-selection ()
  156. "Run `docker-machine-start' on the machines selection."
  157. (interactive)
  158. (--each (docker-utils-get-marked-items-ids)
  159. (docker-machine-run "start" (docker-machine-start-arguments) it))
  160. (tablist-revert))
  161. (defun docker-machine-stop-selection ()
  162. "Run `docker-machine-stop' on the machines selection."
  163. (interactive)
  164. (--each (docker-utils-get-marked-items-ids)
  165. (docker-machine-run "stop" (docker-machine-stop-arguments) it))
  166. (tablist-revert))
  167. (magit-define-popup docker-machine-env-popup
  168. "Popup for setting up environment variables."
  169. 'docker-machine
  170. :man-page "docker-machine-env"
  171. :actions '((?E "Env" docker-machine-env-selection))
  172. :setup-function #'docker-utils-setup-popup)
  173. (magit-define-popup docker-machine-ls-popup
  174. "Popup for listing machines."
  175. 'docker-machine
  176. :man-page "docker-machine-ls"
  177. :options '((?f "Filter" "--filter ")
  178. (?t "Timeout" "--timeout "))
  179. :actions `((?l "List" ,(docker-utils-set-then-call 'docker-machine-ls-arguments 'tablist-revert))))
  180. (magit-define-popup docker-machine-restart-popup
  181. "Popup for restarting machines."
  182. 'docker-machine
  183. :man-page "docker-machine-restart"
  184. :actions '((?R "Restart" docker-machine-restart-selection))
  185. :setup-function #'docker-utils-setup-popup)
  186. (magit-define-popup docker-machine-rm-popup
  187. "Popup for removing machines."
  188. 'docker-machine
  189. :man-page "docker-machine-rm"
  190. :switches '((?f "Force" "-f")
  191. (?y "Automatic yes" "-y"))
  192. :actions '((?D "Remove" docker-machine-rm-selection))
  193. :default-arguments '("-y")
  194. :setup-function #'docker-utils-setup-popup)
  195. (magit-define-popup docker-machine-start-popup
  196. "Popup for starting machines."
  197. 'docker-machine
  198. :man-page "docker-machine-start"
  199. :actions '((?S "Start" docker-machine-start-selection))
  200. :setup-function #'docker-utils-setup-popup)
  201. (magit-define-popup docker-machine-stop-popup
  202. "Popup for stoping machines."
  203. 'docker-machine
  204. :man-page "docker-machine-stop"
  205. :actions '((?O "Stop" docker-machine-stop-selection))
  206. :setup-function #'docker-utils-setup-popup)
  207. (magit-define-popup docker-machine-help-popup
  208. "Help popup for docker machine."
  209. 'docker-machine
  210. :actions '("Docker machines help"
  211. (?C "Create" docker-machine-create)
  212. (?D "Remove" docker-machine-rm-popup)
  213. (?E "Env" docker-machine-env-popup)
  214. (?O "Stop" docker-machine-stop-popup)
  215. (?R "Restart" docker-machine-restart-popup)
  216. (?S "Start" docker-machine-start-popup)
  217. (?l "List" docker-machine-ls-popup)))
  218. (defvar docker-machine-mode-map
  219. (let ((map (make-sparse-keymap)))
  220. (define-key map "?" 'docker-machine-help-popup)
  221. (define-key map "C" 'docker-machine-create)
  222. (define-key map "D" 'docker-machine-rm-popup)
  223. (define-key map "E" 'docker-machine-env-popup)
  224. (define-key map "O" 'docker-machine-stop-popup)
  225. (define-key map "R" 'docker-machine-restart-popup)
  226. (define-key map "S" 'docker-machine-start-popup)
  227. (define-key map "l" 'docker-machine-ls-popup)
  228. map)
  229. "Keymap for `docker-machine-mode'.")
  230. ;;;###autoload
  231. (defun docker-machines ()
  232. "List docker machines."
  233. (interactive)
  234. (docker-utils-pop-to-buffer "*docker-machines*")
  235. (docker-machine-mode)
  236. (tablist-revert))
  237. (define-derived-mode docker-machine-mode tabulated-list-mode "Machines Menu"
  238. "Major mode for handling a list of docker machines."
  239. (setq tabulated-list-format [("Name" 16 t)("Active" 7 t)("Driver" 12 t)("State" 12 t)("URL" 30 t)("Swarm" 10 t)("Docker" 10 t)("Errors" 10 t)])
  240. (setq tabulated-list-padding 2)
  241. (setq tabulated-list-sort-key docker-machine-default-sort-key)
  242. (add-hook 'tabulated-list-revert-hook 'docker-machine-refresh nil t)
  243. (tabulated-list-init-header)
  244. (tablist-minor-mode))
  245. (provide 'docker-machine)
  246. ;;; docker-machine.el ends here