forked from kubernetes-el/kubernetes-el
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkubernetes-utils.el
More file actions
208 lines (174 loc) · 7.7 KB
/
kubernetes-utils.el
File metadata and controls
208 lines (174 loc) · 7.7 KB
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
;; kubernetes-utils.el --- Common utilities. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'dash)
(require 'subr-x)
(require 'term)
(require 'kubernetes-ast)
(require 'kubernetes-core)
(require 'kubernetes-kubectl)
(require 'kubernetes-props)
(require 'kubernetes-state)
(require 'kubernetes-vars)
(autoload 'org-read-date "org")
(defalias 'kubernetes-utils-read-pod-name 'kubernetes-pods--read-name
"Exporting `kubernetes-pods--read-name'")
(defun kubernetes-utils-read-iso-datetime (&rest _)
(let* ((date (org-read-date nil t))
(tz (format-time-string "%z" date)))
(concat
(format-time-string "%Y-%m-%dT%H:%M:%S" date)
(replace-regexp-in-string (rx (group (? (any "+-")) digit digit)
(group digit digit))
"\\1:\\2"
tz))))
(defun kubernetes-get-pod-container-names (pod)
"Return the names of all containers available in the specified POD.
Returns nil on invalid input."
(-let [(&alist 'spec (&alist 'containers containers)) pod]
(-map (-lambda ((&alist 'name name)) name) containers)))
(define-error 'kubernetes-state-error "Kubernetes state not initialized")
(defun kubernetes-utils-read-container-name (&rest _)
"Read a container name from the pod at POINT or a user-supplied pod.
This function will error if `kubernetes-state' is not
initialized."
(letrec ((state (or (kubernetes-state) (signal 'kubernetes-state-error nil)))
(pod-name (or (kubernetes-utils-maybe-pod-name-at-point)
(kubernetes-utils-read-pod-name state)))
(pod (kubernetes-state-lookup-pod pod-name state))
(pod-containers (kubernetes-get-pod-container-names pod)))
(completing-read "Container name: " pod-containers nil t)))
(defun kubernetes-utils-read-time-value (&rest _)
"Read a relative time value in the style accepted by kubectl. E.g. 20s, 3h, 5m."
(let (result)
(while (null result)
(let ((input (read-string "Time value (e.g. 20s): ")))
(if (string-match-p (rx bol (* space) (+ digit) (* space) (any "smh") (* space) eol)
input)
(setq result input)
(message "Invalid time value")
(sit-for 1))))
result))
(defun kubernetes-utils-maybe-pod-name-at-point ()
(when-let ((nav-buffer (get-buffer kubernetes-overview-buffer-name)))
(with-current-buffer nav-buffer
(pcase (get-text-property (point) 'kubernetes-nav nav-buffer)
(`(:pod-name ,value)
value)))))
(defun kubernetes-utils-ellipsize (s threshold)
"Ellipsize a string S that's longer than THRESHOLD.
If that string spans multiple lines, this is further indicated by
a backward slash."
(let* ((lines (split-string s "\n"))
(first-line (car lines))
(ellipsized
(if (> (length first-line) threshold)
(concat (substring first-line 0 (1- threshold)) "...")
first-line)))
(if (> (length lines) 1)
(concat ellipsized (propertize " \\" 'face 'kubernetes-dimmed))
ellipsized)))
(defun kubernetes-utils-parse-utc-timestamp (timestamp)
"Parse TIMESTAMP string from the API into the representation used by Emacs."
(let ((parsed (parse-time-string (replace-regexp-in-string "Z" "" (replace-regexp-in-string "T" " " timestamp)))))
(setf (nth 8 parsed) 0)
parsed))
(defun kubernetes-utils-time-diff-string (start now)
"Find the interval between START and NOW, and return a string of the coarsest unit."
(let ((diff (time-to-seconds (time-subtract now start))))
(car (split-string (format-seconds "%yy,%dd,%hh,%mm,%ss%z" diff) ","))))
(defun kubernetes-utils-make-cleanup-fn (buf)
"Make a function to add to `kill-buffer-hook' for a Kubernetes buffer.
BUF is the buffer used to display a Kubernetes feature. A
reference to it is needed to determine which buffers remain.
The function will terminate polling when the last Kubernetes
buffer is killed."
(lambda ()
(let* ((bufs (-keep #'get-buffer (list kubernetes-label-query-buffer-name
kubernetes-overview-buffer-name)))
(more-buffers (remove buf bufs)))
(unless more-buffers
(dolist (b bufs)
(with-current-buffer b
(kubernetes-state-clear)))
(kubernetes-process-kill-polling-processes)
(kubernetes--kill-timers)))))
(defun kubernetes-utils-term-buffer-start (bufname command args)
;; Kill existing process.
(when-let ((existing (get-buffer bufname))
(proc (get-buffer-process existing)))
(kubernetes-process-kill-quietly proc))
(let ((buf (get-buffer-create bufname)))
(with-current-buffer buf
(erase-buffer)
(buffer-disable-undo)
(term-mode)
(goto-char (point-min))
(let ((time-str (format "Session started at %s" (substring (current-time-string) 0 19)))
(command-str (format "%s %s" command (string-join args " "))))
(kubernetes-ast-eval
`((line ,(propertize time-str 'face 'kubernetes-dimmed))
(padding)
(line ,(propertize command-str 'face 'kubernetes-dimmed))
(padding))))
(term-exec (current-buffer) "kuberenetes-term" command nil args)
(let ((proc (get-buffer-process (current-buffer))))
(set-process-query-on-exit-flag proc nil)
(term-char-mode)
(add-hook 'kill-buffer-hook (lambda ()
(when-let (win (get-buffer-window buf))
(quit-window nil win)))
nil t)))
buf))
(defun kubernetes-utils-vterm-start (bufname command args)
;; Kill existing process.
(when-let ((existing (get-buffer bufname)))
(let ((proc (get-buffer-process existing)))
(if proc
(kubernetes-process-kill-quietly proc)
(kill-buffer bufname))))
(let* ((vterm-buffer-name bufname)
(command-str (format "%s %s" command (string-join args " ")))
(vterm-shell command-str))
(vterm-other-window)))
(defun kubernetes-utils-process-buffer-start (bufname setup-fn command args &optional process-filter)
(let ((buf (get-buffer-create bufname)))
(buffer-disable-undo buf)
(with-current-buffer buf
(let ((inhibit-read-only t))
(erase-buffer)
(funcall setup-fn)
(let ((time-str (format "Process started at %s" (substring (current-time-string) 0 19)))
(command-str (format "%s %s" command (string-join args " "))))
(kubernetes-ast-eval
`((line ,(propertize time-str 'face 'kubernetes-dimmed))
(padding)
(line ,(propertize command-str 'face 'kubernetes-dimmed))
(padding))))))
(let ((proc (apply #'start-process "kubernetes-exec" buf command args)))
(when process-filter
(set-process-filter proc process-filter))
(set-process-query-on-exit-flag proc nil))
buf))
(defun kubernetes-utils-overview-buffer-selected-p ()
(equal (current-buffer) (get-buffer kubernetes-overview-buffer-name)))
(defmacro kubernetes-utils--save-window-state (&rest body)
"Restore window state after executing BODY.
This is useful if the buffer is erased and repopulated in BODY,
in which case `save-excursion' is insufficient to restore the
window state."
`(let ((pos (point))
(col (current-column))
(window-start-line (window-start))
(inhibit-redisplay t))
(save-excursion
,@body)
(goto-char pos)
(move-to-column col)
(set-window-start (selected-window) window-start-line)))
(defun kubernetes-utils-up-to-existing-dir (dir)
(while (not (file-directory-p dir))
(setq dir (file-name-directory (directory-file-name dir))))
dir)
(provide 'kubernetes-utils)
;;; kubernetes-utils.el ends here