diff --git a/docs/how-tos/img/kele-resource-logs.png b/docs/how-tos/img/kele-resource-logs.png new file mode 100644 index 0000000..dc6765b Binary files /dev/null and b/docs/how-tos/img/kele-resource-logs.png differ diff --git a/docs/how-tos/usage.md b/docs/how-tos/usage.md index b933932..91e7576 100644 --- a/docs/how-tos/usage.md +++ b/docs/how-tos/usage.md @@ -111,6 +111,13 @@ separate buffer in a table. From here, you can: You can press `g` in a `kele-get` buffer to re-fetch and refresh the current resource. +### Following logs + +When `kele-resource` is called on a resource that supports logs, you can use the +`l` key to follow the logs for a single resource. + +![](./img/kele-resource-logs.png) + ## Contexts ![](./img/context-prefix.png) diff --git a/docs/index.md b/docs/index.md index c87fe16..7a104d6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,6 +18,7 @@ With Kele, you can: namespace](./how-tos/usage.md#contexts); - [Fetch and display the manifest of a single resource](./how-tos/usage.md#working-with-resources); +- [Follow logs for a single resource](./how-tos/usage.md#following-logs) - [List collections of resources](./how-tos/usage.md#working-with-resources); - Start and stop [proxy servers](./how-tos/usage.md#managing-proxy-servers); - Use the menu bar to perform basic cluster/config management; diff --git a/docs/references/changelog.md b/docs/references/changelog.md index cb1b901..f578e02 100644 --- a/docs/references/changelog.md +++ b/docs/references/changelog.md @@ -16,6 +16,8 @@ versioning][semver]. - `kele-list` now supports kind-specific columns. For example, listing Deployments will now show columns `READY`, `UP-TO-DATE`, and `AVAILABLE`, similar to `kubectl get deployments` +- `kele-resource` now has a keybinding to follow logs for resources that support + it ## 0.6.0 diff --git a/kele.el b/kele.el index 46f5748..255272c 100644 --- a/kele.el +++ b/kele.el @@ -107,6 +107,9 @@ pods." (defvar kele--discovery-last-refresh-time nil "Timestamp of last successful poll of the discovery cache.") +(defvar kele--loggable-kinds '("pods" "deployments" "jobs" "services") + "Resource kinds that can be passed to kubectl log.") + ;; TODO (#80): Display in the `kele-get-mode' header what fields were filtered out (defcustom kele-filtered-fields '((metadata managedFields) (metadata annotations kubectl.kubernetes.io/last-applied-configuration)) @@ -1635,6 +1638,14 @@ prompting and the function simply returns the single option." kind) gvs))))) +(defun kele--get-gvk-arg () + "Get the GVK to use for a command." + (-let* ((kind (kele--get-kind-arg)) + (gv (kele--get-groupversion-arg kind)) + ((group version) (kele--groupversion-split gv))) + (kele--gvk-create :group group :version version :kind kind))) + + (defvar kele--list-context nil "The context corresponding to the current `kele-list-mode' buffer.") @@ -1970,16 +1981,10 @@ to query for." 'warning)) (format "Don't have permission to get %s" .kind)))) (interactive - (-let* ((kind (kele--get-kind-arg)) - (gv (kele--get-groupversion-arg kind)) - ((group version) (kele--groupversion-split gv)) - (gvk (kele--gvk-create - :group group - :version version - :kind kind)) + (-let* ((gvk (kele--get-gvk-arg)) (ns (kele--get-namespace-arg - :group-version gv - :kind kind + :group-version (kele--gv-string gvk) + :kind (oref gvk kind) :permit-nil t :use-default nil)) (cands (kele--fetch-resource-names gvk :namespace ns :context (kele--get-context-arg))) @@ -1998,18 +2003,13 @@ CONTEXT and NAMESPACE are used to identify where the deployment lives." (let-alist (oref transient--prefix scope) (string-equal "deployments" .kind))) (interactive - (let* ((context (kele--get-context-arg)) + (let* ((gvk (kele--gvk-create :kind "deployments" :group "apps" :version "v1")) + (context (kele--get-context-arg)) (ns (kele--get-namespace-arg - :kind "deployments" - :group-version "apps/v1" + :kind (oref gvk kind) + :group-version (kele--gv-string gvk) :use-default nil)) - (cands (kele--fetch-resource-names - (kele--gvk-create - :group "apps" - :version "v1" - :kind "deployments") - :namespace ns - :context context)) + (cands (kele--fetch-resource-names gvk :namespace ns :context context)) (name (completing-read "Deployment to restart: " (-cut kele--resources-complete <> <> <> :cands cands)))) (list context ns name))) @@ -2042,6 +2042,7 @@ CONTEXT and NAMESPACE are used to identify where the deployment lives." (kele--get-kind-for-plural kele--global-discovery-cache it) (propertize it 'face 'warning)) (propertize "-specific actions" 'face 'transient-heading)))) + (kele-resource-follow-logs) (kele-deployment-restart)]] (interactive (let* ((context (kele-current-context-name)) @@ -2061,6 +2062,36 @@ CONTEXT and NAMESPACE are used to identify where the deployment lives." (kind . ,kind) (context . ,(kele-current-context-name))))) +;; TODO: +;; - `kele-log-mode-map' with bindings to change parameters and reload the buffer + +;; FIXME: Known issues: +;; - Might not support multi-container pods +(transient-define-suffix kele-resource-follow-logs (context namespace gvk name) + :key "l" + :if + (lambda () + (let-alist (oref transient--prefix scope) + (-contains? kele--loggable-kinds .kind))) + :description "Follow logs" + (interactive + (-let* ((gvk (kele--get-gvk-arg)) + (ns (kele--get-namespace-arg + :group-version (kele--gv-string gvk) + :kind (oref gvk kind) + :use-default nil)) + (cands (kele--fetch-resource-names gvk :namespace ns :context (kele--get-context-arg))) + (name (completing-read "Name: " (-cut kele--resources-complete <> <> <> :cands cands)))) + (list (kele--get-context-arg) ns gvk name))) + (let* ((buf-name (format "*kele: logs: %s/%s*" (kele--string gvk) name)) + (name-func (lambda (_) buf-name)) + (cmd (format "kubectl logs --follow --context %s --namespace %s %s/%s" + context + namespace + (kele--gvk-kind gvk) + name))) + (compilation-start cmd t name-func))) + (transient-define-prefix kele-dispatch () "Work with Kubernetes clusters and configs." ["Work with..."