From 0dbeb289184f9a5680c0d40d9375f0044292d87d Mon Sep 17 00:00:00 2001 From: Chai Bot Date: Thu, 9 Jul 2026 19:27:25 +0000 Subject: [PATCH] Export pod inspect functions for external consumption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Export the following unexported functions in pkg/cli/admin/inspect/pod.go so they can be imported by external Go packages without vendoring the full oc binary (which pulls in CVE-affected transitive dependencies): - gatherPodData → GatherPodData - gatherContainerInfo → GatherContainerInfo - gatherContainerAllLogs → GatherContainerAllLogs - gatherContainerLogs → GatherContainerLogs - gatherContainerRotatedLogFiles → GatherContainerRotatedLogFiles - filterContainerLogsErrors → FilterContainerLogsErrors - rotatedLogFilename → RotatedLogFilename All internal callers in pod.go and namespace.go are updated to use the new exported names. Godoc comments are added to each exported function per project conventions. No behavioral changes. Co-Authored-By: Claude Opus 4.6 --- pkg/cli/admin/inspect/namespace.go | 2 +- pkg/cli/admin/inspect/pod.go | 48 ++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/pkg/cli/admin/inspect/namespace.go b/pkg/cli/admin/inspect/namespace.go index 1483495bd5..3d741301ca 100644 --- a/pkg/cli/admin/inspect/namespace.go +++ b/pkg/cli/admin/inspect/namespace.go @@ -82,7 +82,7 @@ func (o *InspectOptions) gatherNamespaceData(ctx context.Context, baseDir, names klog.V(1).Infof(" Gathering data for pod %q\n", pod.GetName()) structuredPod := &corev1.Pod{} runtime.DefaultUnstructuredConverter.FromUnstructured(pod.Object, structuredPod) - if err := o.gatherPodData(ctx, path.Join(destDir, "/pods/"+pod.GetName()), namespace, structuredPod); err != nil { + if err := o.GatherPodData(ctx, path.Join(destDir, "/pods/"+pod.GetName()), namespace, structuredPod); err != nil { errs = append(errs, err) continue } diff --git a/pkg/cli/admin/inspect/pod.go b/pkg/cli/admin/inspect/pod.go index 75d810d45d..7966c8c89d 100644 --- a/pkg/cli/admin/inspect/pod.go +++ b/pkg/cli/admin/inspect/pod.go @@ -17,7 +17,9 @@ import ( "k8s.io/klog/v2" ) -func (o *InspectOptions) gatherPodData(ctx context.Context, destDir, namespace string, pod *corev1.Pod) error { +// GatherPodData writes the pod resource YAML to destDir and gathers log +// data for every container (init and regular) defined in the pod spec. +func (o *InspectOptions) GatherPodData(ctx context.Context, destDir, namespace string, pod *corev1.Pod) error { // ensure destination path exists if err := os.MkdirAll(destDir, os.ModePerm); err != nil { return err @@ -32,13 +34,13 @@ func (o *InspectOptions) gatherPodData(ctx context.Context, destDir, namespace s // gather data for each container in the given pod for _, container := range pod.Spec.Containers { - if err := o.gatherContainerInfo(ctx, path.Join(destDir, "/"+container.Name), pod, container); err != nil { + if err := o.GatherContainerInfo(ctx, path.Join(destDir, "/"+container.Name), pod, container); err != nil { errs = append(errs, err) continue } } for _, container := range pod.Spec.InitContainers { - if err := o.gatherContainerInfo(ctx, path.Join(destDir, "/"+container.Name), pod, container); err != nil { + if err := o.GatherContainerInfo(ctx, path.Join(destDir, "/"+container.Name), pod, container); err != nil { errs = append(errs, err) continue } @@ -50,28 +52,32 @@ func (o *InspectOptions) gatherPodData(ctx context.Context, destDir, namespace s return nil } -func (o *InspectOptions) gatherContainerInfo(ctx context.Context, destDir string, pod *corev1.Pod, container corev1.Container) error { - if err := o.gatherContainerAllLogs(ctx, path.Join(destDir, "/"+container.Name), pod, &container); err != nil { +// GatherContainerInfo collects all available log data for a single container +// within the given pod and writes it under destDir. +func (o *InspectOptions) GatherContainerInfo(ctx context.Context, destDir string, pod *corev1.Pod, container corev1.Container) error { + if err := o.GatherContainerAllLogs(ctx, path.Join(destDir, "/"+container.Name), pod, &container); err != nil { return err } return nil } -func (o *InspectOptions) gatherContainerAllLogs(ctx context.Context, destDir string, pod *corev1.Pod, container *corev1.Container) error { +// GatherContainerAllLogs gathers current and previous container logs, and +// optionally rotated log files when rotated pod log collection is enabled. +func (o *InspectOptions) GatherContainerAllLogs(ctx context.Context, destDir string, pod *corev1.Pod, container *corev1.Container) error { // ensure destination path exists if err := os.MkdirAll(destDir, os.ModePerm); err != nil { return err } errs := []error{} - if err := o.gatherContainerLogs(ctx, path.Join(destDir, "/logs"), pod, container); err != nil { - errs = append(errs, filterContainerLogsErrors(err)) + if err := o.GatherContainerLogs(ctx, path.Join(destDir, "/logs"), pod, container); err != nil { + errs = append(errs, FilterContainerLogsErrors(err)) } if o.rotatedPodLogs { - if err := o.gatherContainerRotatedLogFiles(ctx, path.Join(destDir, "/logs/rotated"), pod, container); err != nil { - errs = append(errs, filterContainerLogsErrors(err)) + if err := o.GatherContainerRotatedLogFiles(ctx, path.Join(destDir, "/logs/rotated"), pod, container); err != nil { + errs = append(errs, FilterContainerLogsErrors(err)) } } if len(errs) > 0 { @@ -80,7 +86,10 @@ func (o *InspectOptions) gatherContainerAllLogs(ctx context.Context, destDir str return nil } -func filterContainerLogsErrors(err error) error { +// FilterContainerLogsErrors filters out expected transient errors from +// container log retrieval, such as "previous terminated container ... not found". +// It returns nil for those cases and passes through all other errors unchanged. +func FilterContainerLogsErrors(err error) error { if strings.Contains(err.Error(), "previous terminated container") && strings.HasSuffix(err.Error(), "not found") { klog.V(1).Infof(" Unable to gather previous container logs: %v\n", err) return nil @@ -88,7 +97,10 @@ func filterContainerLogsErrors(err error) error { return err } -func rotatedLogFilename(pod *corev1.Pod) (string, error) { +// RotatedLogFilename returns the on-disk log directory name for the given pod. +// For static pods (source "file") it uses the config hash annotation; for all +// other pods it uses the pod UID. +func RotatedLogFilename(pod *corev1.Pod) (string, error) { if value, exists := pod.Annotations["kubernetes.io/config.source"]; exists && value == "file" { hash, exists := pod.Annotations["kubernetes.io/config.hash"] if !exists { @@ -99,11 +111,14 @@ func rotatedLogFilename(pod *corev1.Pod) (string, error) { return pod.Namespace + "_" + pod.Name + "_" + string(pod.GetUID()), nil } -func (o *InspectOptions) gatherContainerRotatedLogFiles(ctx context.Context, destDir string, pod *corev1.Pod, container *corev1.Container) error { +// GatherContainerRotatedLogFiles retrieves rotated log files for a container +// from the node's filesystem via the kubelet proxy, honouring any --since or +// --since-time constraints. +func (o *InspectOptions) GatherContainerRotatedLogFiles(ctx context.Context, destDir string, pod *corev1.Pod, container *corev1.Container) error { restClient := o.kubeClient.CoreV1().RESTClient() var innerErrs []error - logFileName, err := rotatedLogFilename(pod) + logFileName, err := RotatedLogFilename(pod) if err != nil { return err } @@ -194,7 +209,10 @@ func (o *InspectOptions) gatherContainerRotatedLogFiles(ctx context.Context, des return utilerrors.NewAggregate(innerErrs) } -func (o *InspectOptions) gatherContainerLogs(ctx context.Context, destDir string, pod *corev1.Pod, container *corev1.Container) error { +// GatherContainerLogs retrieves the current and previous container logs for +// the specified container and writes them to destDir. If the initial request +// fails it retries with InsecureSkipTLSVerifyBackend enabled. +func (o *InspectOptions) GatherContainerLogs(ctx context.Context, destDir string, pod *corev1.Pod, container *corev1.Container) error { // ensure destination path exists if err := os.MkdirAll(destDir, os.ModePerm); err != nil { return err