@@ -2,6 +2,7 @@ package main
22
33import (
44 "bufio"
5+ "bytes"
56 "context"
67 "fmt"
78 "io"
@@ -12,6 +13,7 @@ import (
1213
1314 "github.com/fatih/color"
1415 "github.com/spf13/cobra"
16+ "github.com/stackrox/roxie/internal/logger"
1517)
1618
1719var (
@@ -43,7 +45,38 @@ func newLogsOperatorCmd() *cobra.Command {
4345 return cmd
4446}
4547
46- func runLogsOperator (cmd * cobra.Command , args []string ) error {
48+ // validateClusterConnection checks if the cluster is reachable.
49+ func validateClusterConnection (logger logger.Logger , ctx context.Context ) error {
50+ cmd := exec .CommandContext (ctx , "kubectl" , "get" , "namespaces" )
51+
52+ var stderr bytes.Buffer
53+ cmd .Stderr = & stderr
54+ cmd .Stdout = io .Discard
55+
56+ if err := cmd .Run (); err != nil {
57+ for _ , stderrLine := range strings .Split (stderr .String (), "\n " ) {
58+ logger .Dim (stderrLine )
59+ }
60+ if ctx .Err () == context .DeadlineExceeded {
61+ return fmt .Errorf ("timeout connecting to cluster - ensure your kubeconfig is correct and the cluster is reachable" )
62+ }
63+ return fmt .Errorf ("failed to connect to cluster: %w" , err )
64+ }
65+ return nil
66+ }
67+
68+ func runLogsOperator (_ * cobra.Command , args []string ) error {
69+ logger := logger .New ()
70+
71+ // Validate cluster connection first (fast-fail)
72+ validateCtx , validateCancel := context .WithTimeout (context .Background (), 30 * time .Second )
73+ defer validateCancel ()
74+
75+ if err := validateClusterConnection (logger , validateCtx ); err != nil {
76+ validateCancel ()
77+ return err
78+ }
79+
4780 // Build kubectl command
4881 kubectlArgs := []string {
4982 "-n" , "rhacs-operator-system" ,
@@ -55,13 +88,8 @@ func runLogsOperator(cmd *cobra.Command, args []string) error {
5588 kubectlArgs = append (kubectlArgs , "-f" )
5689 }
5790
58- // Create context with timeout for initial connection
59- // Use a longer timeout (30s) to allow for cluster connection
60- ctx , cancel := context .WithTimeout (context .Background (), 30 * time .Second )
61- defer cancel ()
62-
63- // Create kubectl command with context
64- kubectlCmd := exec .CommandContext (ctx , "kubectl" , kubectlArgs ... )
91+ // Create kubectl command without context - allows indefinite streaming.
92+ kubectlCmd := exec .Command ("kubectl" , kubectlArgs ... )
6593
6694 // Get stdout pipe for streaming
6795 stdout , err := kubectlCmd .StdoutPipe ()
@@ -82,10 +110,6 @@ func runLogsOperator(cmd *cobra.Command, args []string) error {
82110
83111 // Wait for command to complete
84112 if err := kubectlCmd .Wait (); err != nil {
85- // Check if it was a timeout
86- if ctx .Err () == context .DeadlineExceeded {
87- return fmt .Errorf ("timeout connecting to cluster - ensure your kubeconfig is correct and the cluster is reachable" )
88- }
89113 // Don't return error if kubectl was interrupted (e.g., Ctrl+C)
90114 if _ , ok := err .(* exec.ExitError ); ok {
91115 return nil
0 commit comments