diff --git a/README.md b/README.md index 744a4d73..4c27ae42 100644 --- a/README.md +++ b/README.md @@ -317,6 +317,8 @@ Get the logs of a Kubernetes Pod in the current or provided namespace with the p - Namespace to get the Pod logs from - `container` (`string`, optional) - Name of the Pod container to get logs from +- `previous` (`boolean`, optional) + - Return previous terminated container logs ### `pods_run` diff --git a/pkg/kubernetes/pods.go b/pkg/kubernetes/pods.go index b6a12447..180eb720 100644 --- a/pkg/kubernetes/pods.go +++ b/pkg/kubernetes/pods.go @@ -92,7 +92,7 @@ func (k *Kubernetes) PodsDelete(ctx context.Context, namespace, name string) (st k.ResourcesDelete(ctx, &schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"}, namespace, name) } -func (k *Kubernetes) PodsLog(ctx context.Context, namespace, name, container string) (string, error) { +func (k *Kubernetes) PodsLog(ctx context.Context, namespace, name, container string, previous bool) (string, error) { tailLines := int64(256) pods, err := k.manager.accessControlClientSet.Pods(k.NamespaceOrDefault(namespace)) if err != nil { @@ -101,6 +101,7 @@ func (k *Kubernetes) PodsLog(ctx context.Context, namespace, name, container str req := pods.GetLogs(name, &v1.PodLogOptions{ TailLines: &tailLines, Container: container, + Previous: previous, }) res := req.Do(ctx) if res.Error() != nil { diff --git a/pkg/mcp/pods.go b/pkg/mcp/pods.go index 0150031d..a29f9920 100644 --- a/pkg/mcp/pods.go +++ b/pkg/mcp/pods.go @@ -99,6 +99,7 @@ func (s *Server) initPods() []server.ServerTool { mcp.WithString("namespace", mcp.Description("Namespace to get the Pod logs from")), mcp.WithString("name", mcp.Description("Name of the Pod to get the logs from"), mcp.Required()), mcp.WithString("container", mcp.Description("Name of the Pod container to get the logs from (Optional)")), + mcp.WithBoolean("previous", mcp.Description("Return previous terminated container logs (Optional)")), // Tool annotations mcp.WithTitleAnnotation("Pods: Log"), mcp.WithReadOnlyHintAnnotation(true), @@ -284,11 +285,16 @@ func (s *Server) podsLog(ctx context.Context, ctr mcp.CallToolRequest) (*mcp.Cal if container == nil { container = "" } + previous := ctr.GetArguments()["previous"] + var previousBool bool + if previous != nil { + previousBool = previous.(bool) + } derived, err := s.k.Derived(ctx) if err != nil { return nil, err } - ret, err := derived.PodsLog(ctx, ns.(string), name.(string), container.(string)) + ret, err := derived.PodsLog(ctx, ns.(string), name.(string), container.(string), previousBool) if err != nil { return NewTextResult("", fmt.Errorf("failed to get pod %s log in namespace %s: %v", name, ns, err)), nil } else if ret == "" { diff --git a/pkg/mcp/pods_test.go b/pkg/mcp/pods_test.go index de65afa4..583b1391 100644 --- a/pkg/mcp/pods_test.go +++ b/pkg/mcp/pods_test.go @@ -719,6 +719,36 @@ func TestPodsLog(t *testing.T) { return } }) + podsPreviousLogInNamespace, err := c.callTool("pods_log", map[string]interface{}{ + "namespace": "ns-1", + "name": "a-pod-in-ns-1", + "previous": true, + }) + t.Run("pods_log with previous=true returns previous pod log", func(t *testing.T) { + if err != nil { + t.Fatalf("call tool failed %v", err) + return + } + if podsPreviousLogInNamespace.IsError { + t.Fatalf("call tool failed") + return + } + }) + podsPreviousLogFalse, err := c.callTool("pods_log", map[string]interface{}{ + "namespace": "ns-1", + "name": "a-pod-in-ns-1", + "previous": false, + }) + t.Run("pods_log with previous=false returns current pod log", func(t *testing.T) { + if err != nil { + t.Fatalf("call tool failed %v", err) + return + } + if podsPreviousLogFalse.IsError { + t.Fatalf("call tool failed") + return + } + }) }) }