This macro also defines a prefix keymap, `kubed-RESOURCE-prefix-map',
with bindings for the above commands.
-PROPERTIES is a list of elements (PROPERTY JSON-PATH WIDTH SORT . ATTRS)
-that specify properties of RESOURCEs. PROPERTY is the name of the
-property, as a symbol; JSON-PATH is a JSONPath expression that evaluates
-to the value of PROPERTY when applied to the full JSON representation of
-a RESOURCE. WIDTH, SORT and ATTRS are optional and can be omitted.
-WIDTH is used as the default width of the column corresponding to
-PROPERTY in RESOURCEs list buffers; SORT is sort predicate, a function
-that takes two values of PROPERTY as strings and return non-nil if the
-first should sort before the second; ATTRS is a plist of additional
-attributes of the PROPERTY column, see `tabulated-list-format' for
-available attributes. For example, (phase \".status.phase\" 10) says
-that RESOURCE has a `phase' property at JSONPath \".status.phase\" whose
-values are typically 10 columns wide. The first property in PROPERTIES,
-is used to annotate completion candidates when prompting for a RESOURCE.
+PROPERTIES is a list of lists (PROP JSON-PATH WIDTH SORT FORMAT . ATTRS)
+that specify properties of RESOURCEs. PROP is the name of the property,
+as a symbol; JSON-PATH is a JSONPath expression that evaluates to the
+value of PROP when applied to the JSON representation of a RESOURCE.
+WIDTH, SORT, FORMAT and ATTRS are optional and can be omitted. WIDTH is
+used as the default width of the column corresponding to PROP in
+RESOURCEs list buffers; SORT is sort predicate, a function that takes
+two values of PROP as strings and return non-nil if the first should
+sort before the second; FORMAT is a function that takes a value of PROP
+and formats it; and ATTRS is a plist of additional attributes of the
+PROP column, see `tabulated-list-format' for available attributes. For
+example, (phase \".status.phase\" 10) says that RESOURCE has a `phase'
+property at JSONPath \".status.phase\" whose values are typically 10
+columns wide. The first property in PROPERTIES, is used to annotate
+completion candidates when prompting for a RESOURCE.
COMMANDS is a list of elements (COMMAND KEYS DOC-PREFIX . BODY) that
define commands for RESOURCE list buffers. COMMAND is a symbol
(cadr p)))
properties)))
",")))
- :sentinel (lambda (_proc status)
- (cond
- ((string= status "finished\n")
- (let (new offsets eol)
- (with-current-buffer ,out-name
- (goto-char (point-min))
- (setq eol (pos-eol))
- (while (re-search-forward "[^ ]+" eol t)
- (push (1- (match-beginning 0)) offsets))
- (setq offsets (nreverse offsets))
- (forward-char 1)
- (while (not (eobp))
- (let ((cols nil)
- (beg (car offsets))
- (ends (cdr offsets)))
- (dolist (end ends)
- (push (string-trim (buffer-substring
- (+ (point) beg)
- (+ (point) end)))
- cols)
- (setq beg end))
- (push (string-trim (buffer-substring
- (+ (point) beg)
- (pos-eol)))
- cols)
- (push (nreverse cols) new))
- (forward-line 1)))
- (setq ,list-var new
- ,proc-var nil)
- (run-hooks ',hook-var)
- (message ,(format "Updated Kubernetes %Ss." resource))))
- ((string= status "exited abnormally with code 1\n")
- (with-current-buffer ,err-name
- (goto-char (point-max))
- (insert "\n" status))
- (display-buffer ,err-name))))))
+ :sentinel
+ (lambda (_proc status)
+ (cond
+ ((string= status "finished\n")
+ (let (new offsets eol)
+ (with-current-buffer ,out-name
+ (goto-char (point-min))
+ (setq eol (pos-eol))
+ (while (re-search-forward "[^ ]+" eol t)
+ (push (1- (match-beginning 0)) offsets))
+ (setq offsets (nreverse offsets))
+ (forward-char 1)
+ (while (not (eobp))
+ (let ((cols nil)
+ (beg (car offsets))
+ (ends (append (cdr offsets) (list (- (pos-eol) (point))))))
+ ,@(let ((read-col
+ (lambda (p)
+ ;; Fresh list to avoid circles.
+ (list `(push ,(if-let ((f (nth 4 p)))
+ `(funcall ,f (string-trim (buffer-substring
+ (+ (point) beg)
+ (+ (point) (car ends)))))
+ `(string-trim (buffer-substring
+ (+ (point) beg)
+ (+ (point) (car ends)))))
+ cols)
+ '(setq beg (pop ends))))))
+ (if namespaced
+ ;; Resource is namespaced, generate
+ ;; code that is sensitive to
+ ;; `kubed-all-namespaces-mode'.
+ `((if kubed-all-namespaces-mode
+ (progn
+ ,@(mapcan
+ read-col
+ ;; Two nils, one for the
+ ;; name column, another
+ ;; for the namespace.
+ `(nil nil . ,properties)))
+ ,@(mapcan read-col `(nil . ,properties))))
+ ;; Non-namespaced.
+ (mapcan read-col `(nil . ,properties))))
+ (push (nreverse cols) new))
+ (forward-line 1)))
+ (setq ,list-var new
+ ,proc-var nil)
+ (run-hooks ',hook-var)
+ (message ,(format "Updated Kubernetes %Ss." resource))))
+ ((string= status "exited abnormally with code 1\n")
+ (with-current-buffer ,err-name
+ (goto-char (point-max))
+ (insert "\n" status))
+ (display-buffer ,err-name))))))
(minibuffer-message ,(format "Updating Kubernetes %Ss..." resource)))
(defun ,affx-fun (,plrl-var)
(funcall ,sorter (aref (cadr l) c) (aref (cadr r) c)))
`(funcall ,sorter (aref (cadr l) ,i) (aref (cadr r) ,i))))
t))
- (nthcdr 4 p))
+ (nthcdr 5 p))
res))
(reverse res)))
;;;###autoload (autoload 'kubed-create-pod "kubed" nil t)
;;;###autoload (autoload 'kubed-pod-prefix-map "kubed" nil t 'keymap)
(kubed-define-resource pod
- ((phase ".status.phase" 10) (starttime ".status.startTime" 20))
+ ((phase ".status.phase" 10
+ nil ; sorting function
+ (lambda (ph)
+ (if-let ((face (pcase ph
+ ;; TODO: Define/derive bespoke faces.
+ ("Pending" 'warning)
+ ("Running" 'success)
+ ("Succeeded" 'shadow)
+ ("Failed" 'error))))
+ (propertize ph 'face face)
+ ph)))
+ (ready ".status.containerStatuses[?(.ready==true)].name" 6
+ (lambda (l r) (< (string-to-number l) (string-to-number r)))
+ (lambda (cs)
+ (if (string= cs "<none>") "0"
+ (number-to-string (1+ (seq-count (lambda (c) (= c ?,)) cs)))))
+ :right-align t)
+ (total ".status.containerStatuses[*].name" 6
+ (lambda (l r) (< (string-to-number l) (string-to-number r)))
+ (lambda (cs)
+ (if (string= cs "<none>") "0"
+ (number-to-string (1+ (seq-count (lambda (c) (= c ?,)) cs)))))
+ :right-align t)
+ (starttime ".status.startTime" 20))
:prefix ("L" #'kubed-logs
"A" #'kubed-attach
"X" #'kubed-exec
;;;###autoload (autoload 'kubed-create-namespace "kubed" nil t)
;;;###autoload (autoload 'kubed-namespace-prefix-map "kubed" nil t 'keymap)
(kubed-define-resource namespace
- ((phase ".status.phase" 10)
+ ((phase ".status.phase" 10
+ nil ; sorting function
+ (lambda (ph)
+ (if-let ((face (pcase ph
+ ;; TODO: Define/derive bespoke faces.
+ ("Active" 'success)
+ ("Terminating" 'shadow))))
+ (propertize ph 'face face)
+ ph)))
(creationtimestamp ".metadata.creationTimestamp" 20))
:namespaced nil
:prefix ("S" #'kubed-set-namespace)
(kubed-define-resource deployment
((reps ".status.replicas" 4
(lambda (l r) (< (string-to-number l) (string-to-number r)))
+ nil ; formatting function
:right-align t)
(creationtimestamp ".metadata.creationTimestamp" 20))
:create
(kubed-define-resource replicaset
((reps ".status.replicas" 4
(lambda (l r) (< (string-to-number l) (string-to-number r)))
+ nil ; formatting function
:right-align t)
(ownerkind ".metadata.ownerReferences[0].kind" 12)
(ownername ".metadata.ownerReferences[0].name" 16)
(kubed-define-resource statefulset
((reps ".status.replicas" 4
(lambda (l r) (< (string-to-number l) (string-to-number r)))
+ nil ; formatting function
:right-align t)
(ownerkind ".metadata.ownerReferences[0].kind" 12)
(ownername ".metadata.ownerReferences[0].name" 16)