]> git.eshelyaron.com Git - emacs.git/commitdiff
New commands 'kubed{-transient}-exec'
authorEshel Yaron <me@eshelyaron.com>
Fri, 26 Jul 2024 13:57:50 +0000 (15:57 +0200)
committerEshel Yaron <me@eshelyaron.com>
Fri, 26 Jul 2024 13:57:50 +0000 (15:57 +0200)
lisp/net/kubed-transient.el
lisp/net/kubed.el

index cb91e3fa3b1a437e32f0b801df6f119c2966b806..b7f23afbb62341e088fdbdba090a78dc91128c88 100644 (file)
@@ -63,7 +63,7 @@
    ("!" "Command line" kubed-kubectl-command)]
   (interactive)
   (transient-setup 'kubed-transient-attach nil nil
-                   :value '("--stdin")
+                   :value '("--stdin" "--tty")
                    :scope '("attach")))
 
 ;;;###autoload
   (transient-setup 'kubed-transient-diff nil nil
                    :scope '("diff")))
 
+;;;###autoload
+(transient-define-prefix kubed-transient-exec ()
+  "Execute command in Kubernetes pod."
+  ["Switches"
+   ("-i" "Open stdin" "--stdin")
+   ("-t" "Allocate TTY" "--tty")]
+  ["Options"
+   ("-n" "Namespace" "--namespace="
+    :prompt "Namespace" :reader kubed-transient-read-namespace)
+   ("--" "Command" "-- ="
+    :prompt "Command: ")]
+  ["Actions"
+   ("x" "Execute" kubed-exec)
+   ("!" "Command line" kubed-kubectl-command)]
+  (interactive)
+  (transient-setup 'kubed-transient-exec nil nil
+                   :value '("--stdin" "--tty")
+                   :scope '("exec")))
+
 ;;;###autoload
 (transient-define-prefix kubed-transient-run ()
   "Run container image in a Kubernetes pod."
index 8c2e80cc4e356e0f44f01d5e34dc60b2cd55a804..838e9e84b58581574cd32efc6f871e2a712c24be 100644 (file)
@@ -846,6 +846,7 @@ Optional argument DEFAULT is the minibuffer default argument." resource)
     ((phase ".status.phase" 10) (starttime ".status.startTime" 20))
   :prefix ("L" #'kubed-logs
            "A" #'kubed-attach
+           "X" #'kubed-exec
            "F" #'kubed-forward-port-to-pod)
   (dired "C-d" "Start Dired in home directory of first container of"
          (let ((ns (when k8sns (concat "%" k8sns))))
@@ -857,6 +858,11 @@ Optional argument DEFAULT is the minibuffer default argument." resource)
   (attach "a" "Attach to remote process running on"
           (kubed-attach pod (kubed-read-container pod "Container" t k8sns)
                         k8sns t t))
+  (exec "X" "Execute command in"
+        (let ((container (kubed-read-container pod "Container" t k8sns))
+              (cmd-args (split-string-and-unquote
+                         (read-string "Execute command: "))))
+          (kubed-exec pod (car cmd-args) container k8sns t t (cdr cmd-args))))
   (logs "l" "Show logs for a container of"
         (kubed-logs pod (kubed-read-container pod "Container" t k8sns)))
   (forward-port "F" "Forward local network port to remote port of"
@@ -1464,6 +1470,64 @@ argument) says to include managed fields in the comparison."
       (goto-char (point-min)))
     (display-buffer buf)))
 
+;;;###autoload
+(defun kubed-exec (pod command &optional container namespace stdin tty args)
+  "Execute COMMAND with ARGS in CONTAINER in Kubernetes POD.
+
+Optional argument NAMESPACE is the namespace in which to look for POD.
+Non-nil STDIN says to connect local standard input to remote process.
+Non-nil TTY says to use a TTY for standard input.
+
+Interactively, prompt for POD; if there are multiple pod containers,
+prompt for CONTAINER as well; STDIN is t unless you call this command
+with \\[universal-argument] \\[universal-argument]; and TTY is t unless\
+ you call this command with \\[universal-argument]."
+  (interactive
+   (let ((namespace nil) (stdin t) (tty t) (command nil) (args nil))
+     (when (<= 4  (prefix-numeric-value current-prefix-arg)) (setq tty   nil))
+     (when (<= 16 (prefix-numeric-value current-prefix-arg)) (setq stdin nil))
+     (dolist (arg (kubed-transient-args 'kubed-transient-exec))
+       (cond
+        ((string-match "--namespace=\\(.+\\)" arg)
+         (setq namespace (match-string 1 arg)))
+        ((equal "--stdin" arg) (setq stdin t))
+        ((equal "--tty" arg) (setq tty t))
+        ((string-match "-- =\\(.+\\)" arg)
+         (setq args    (split-string-and-unquote (match-string 1 arg))
+               command (car args)
+               args    (cdr args)))))
+     (if (and kubed-all-namespaces-mode (not namespace))
+         (let* ((p-s (kubed-read-namespaced-pod "Execute command in pod"))
+                (p (car p-s))
+                (s (cadr p-s))
+                (c (kubed-read-container p "Container" t s)))
+           (unless command
+             (setq args    (split-string-and-unquote
+                            (read-string "Execute command: "))
+                   command (car args)
+                   args    (cdr args)))
+           (list p command c s stdin tty args))
+       ;; FIXME: Similarly to `kubed-attach', when namespace is set from
+       ;; transient prefix, read pod name in that namespace instead.
+       (let* ((p (kubed-read-pod "Execute command in pod"))
+              (c (kubed-read-container p "Container" t namespace)))
+         (unless command
+           (setq args    (split-string-and-unquote
+                          (read-string "Execute command: "))
+                 command (car args)
+                 args    (cdr args)))
+         (list p command c namespace stdin tty args)))))
+  (pop-to-buffer
+   (apply #'make-comint "kubed-exec" kubed-kubectl-program nil
+          "exec" pod
+          (append
+           (when namespace (list "-n" namespace))
+           (when container (list "-c" container))
+           (when stdin '("-i"))
+           (when tty '("-t"))
+           (list "--" command)
+           args))))
+
 (defvar kubed-kubectl-command-history nil
   "Minibuffer history for `kubed-kubectl-command'.")