-
Notifications
You must be signed in to change notification settings - Fork 6
/
ecloud-commands.el
114 lines (98 loc) · 4.73 KB
/
ecloud-commands.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
;;; ecloud-commands.el --- Handle external commands. -*- lexical-binding: t; -*-
;; Copyright (C) 2018 The Ecloud Contributors
;; Author: Ramanathan Sivagurunathan <ramzthecoder+ecloud@gmail.com>
;; Version: 0.0.1
;; Package-Requires: ((emacs "25.1") (dash "2.14.1") (magit "2.13.0") (ht "2.2") (s "1.12.0") (pcache "0.4.2"))
;; 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:
;; Code to run an external command.
;;; Code:
(require 'json)
(defun ecloud-process-kill-quietly (proc &optional _signal)
"Function to kill a process quietly for `PROC."
(when proc
(set-process-sentinel proc nil)
(set-process-query-on-exit-flag proc nil)
(let ((kill-buffer-query-functions nil)
(buf (process-buffer proc)))
(ignore-errors (kill-process proc))
(ignore-errors (delete-process proc))
(ignore-errors (kill-buffer buf)))))
(defun ecloud-run-command (cmd args on-success &optional on-error cleanup-cb)
"Run a command CMD with ARGS.
ON-SUCCESS is a function of one argument, called with the process' buffer.
Optional ON-ERROR is a function of two arguments, called with the
process' stderr buffer. If omitted, it defaults to
`kubernetes-kubectl--default-error-handler', which logs an error
if the process exited unexpectedly.
Optional CLEANUP-CB is a function of no arguments that is always
called after the other callbacks. It can be used for releasing
resources.
After callbacks are executed, the process and its buffer will be killed.
Returns the process object for this execution of kubectl."
(let* ((buf (generate-new-buffer " ecloud"))
(err-buf (generate-new-buffer " ecloud-err"))
(command (append cmd args ))
(cloud (cond ((string= "az" (car cmd)) 'azure)
((string= "gcloud" (car cmd)) 'gcp)
((string= "aws" (car cmd)) 'aws)))
;; `default-directory' must exist, otherwise `make-process' raises an
;; error.
;; (default-directory (kubernetes-utils-up-to-existing-dir default-directory))
(proc (make-process
:name "ecloud"
:buffer buf
:stderr err-buf
:command command
:noquery t
:sentinel
(lambda (proc status)
(unwind-protect
(let ((exit-code (process-exit-status proc)))
(cond
;; Success Handler
((zerop exit-code) (funcall on-success buf))
;; Failure Handler
(t
(let ((err-message (with-current-buffer err-buf (buffer-string))))
(unless (= 9 exit-code)
(progn
(ecloud-state-add-error cloud (string-join (append (list (format "[%s]:%s" (current-time-string) status)) command) " ") err-message)
(cond (on-error (funcall on-error err-buf)))
))))))
(when cleanup-cb
(funcall cleanup-cb))
(ecloud-process-kill-quietly proc)))
)))
;; Clean up stderr buffer when stdout buffer is killed.
(with-current-buffer buf
(add-hook 'kill-buffer-hook (lambda ()
(let ((kill-buffer-query-functions nil))
(ignore-errors (kill-buffer err-buf))))
nil t))
proc))
(defun ecloud-parse-json-buffer (buf)
"Function to parse json buffer `BUF."
(let* ((output (with-current-buffer buf (buffer-string))))
(if (> (string-bytes output) 0)
(json-read-from-string output)
nil)))
(defun ecloud-run-json-command (cmd args on-success &optional on-error cleanup-cb)
"Function to run a external command `CMD with `ARGS.
Pass `ON-SUCCESS `ON-ERROR `CLEANUP-CB callbacks."
(ecloud-run-command cmd args
(lambda (buf)
(funcall on-success (ecloud-parse-json-buffer buf)))
on-error
cleanup-cb))
(provide 'ecloud-commands)
;;; ecloud-commands.el ends here