diff --git a/internal/client/client.go b/internal/client/client.go index 7669a86e..7c287284 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -22,23 +22,25 @@ import ( ) const ( - cacheSize = 100 - cacheExpiry = 5 * time.Minute - cacheMXKey = "metrics" + cacheSize = 100 + cacheExpiry = 5 * time.Minute + cacheMXKey = "metrics" + checkConnTimeout = 10 * time.Second ) var supportedMetricsAPIVersions = []string{"v1beta1"} // APIClient represents a Kubernetes api client. type APIClient struct { - client kubernetes.Interface - dClient dynamic.Interface - nsClient dynamic.NamespaceableResourceInterface - mxsClient *versioned.Clientset - cachedClient *disk.CachedDiscoveryClient - config *Config - mx sync.Mutex - cache *cache.LRUExpireCache + checkClientSet *kubernetes.Clientset + client kubernetes.Interface + dClient dynamic.Interface + nsClient dynamic.NamespaceableResourceInterface + mxsClient *versioned.Clientset + cachedClient *disk.CachedDiscoveryClient + config *Config + mx sync.Mutex + cache *cache.LRUExpireCache } // InitConnectionOrDie initialize connection from command line args. @@ -134,17 +136,26 @@ func (a *APIClient) CheckConnectivity() (status bool) { } }() - client, ok := a.DialOrDie().(*kubernetes.Clientset) - if !ok { - return status + if a.checkClientSet == nil { + cfg, err := a.config.flags.ToRESTConfig() + if err != nil { + return + } + cfg.Timeout = checkConnTimeout + + if a.checkClientSet, err = kubernetes.NewForConfig(cfg); err != nil { + log.Error().Err(err).Msgf("Unable to connect to api server") + return + } } - if _, err := client.ServerVersion(); err != nil { + + if _, err := a.checkClientSet.ServerVersion(); err != nil { log.Error().Err(err).Msgf("K9s can't connect to cluster") } else { status = true } - return status + return } // Config return a kubernetes configuration. diff --git a/internal/client/config.go b/internal/client/config.go index 1ba0f5f8..bcfec129 100644 --- a/internal/client/config.go +++ b/internal/client/config.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "sync" - "time" "github.com/rs/zerolog/log" v1 "k8s.io/api/core/v1" @@ -15,9 +14,8 @@ import ( ) const ( - defaultQPS = 100 - defaultBurst = 50 - defaultTimeout = 10 * time.Second + defaultQPS = 50 + defaultBurst = 50 ) // Config tracks a kubernetes configuration. @@ -289,7 +287,6 @@ func (c *Config) RESTConfig() (*restclient.Config, error) { } c.restConfig.QPS = defaultQPS c.restConfig.Burst = defaultBurst - c.restConfig.Timeout = defaultTimeout log.Debug().Msgf("Connecting to API Server %s", c.restConfig.Host) return c.restConfig, nil diff --git a/internal/dao/pod.go b/internal/dao/pod.go index cff6cbf3..1258af29 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -249,6 +249,7 @@ func readLogs(ctx context.Context, stream io.ReadCloser, c chan<- string, opts L c <- opts.DecorateLog(scanner.Text()) } } + log.Error().Msgf("SCAN_ERR %#v", scanner.Err()) } // ---------------------------------------------------------------------------- diff --git a/internal/model/log.go b/internal/model/log.go index 93ea93d8..933864b8 100644 --- a/internal/model/log.go +++ b/internal/model/log.go @@ -137,7 +137,9 @@ func (l *Log) load() error { } if err := logger.TailLogs(ctx, c, l.logOptions); err != nil { - l.cancelFn() + if l.cancelFn != nil { + l.cancelFn() + } close(c) return err } @@ -150,7 +152,6 @@ func (l *Log) Append(line string) { if line == "" { return } - log.Debug().Msgf("LINE %q", line) l.mx.Lock() defer l.mx.Unlock() @@ -168,7 +169,6 @@ func (l *Log) Append(line string) { if l.lastSent < 0 { l.lastSent = 0 } - log.Debug().Msgf("LINES %v -- %v", l.lines, l.lastSent) } // Notify fires of notifications to the listeners. @@ -176,7 +176,7 @@ func (l *Log) Notify(timedOut bool) { l.mx.Lock() defer l.mx.Unlock() - if timedOut || l.lastSent < len(l.lines) { + if timedOut && l.lastSent < len(l.lines) { l.fireLogBuffChanged(l.lines[l.lastSent:]) l.lastSent = len(l.lines) } @@ -225,6 +225,9 @@ func (l *Log) RemoveListener(listener LogsListener) { } func applyFilter(q string, lines []string) ([]string, error) { + if q == "" { + return lines, nil + } indexes, err := filter(q, lines) if err != nil { return nil, err diff --git a/internal/model/log_test.go b/internal/model/log_test.go index bb3fd6cc..ddb3efcb 100644 --- a/internal/model/log_test.go +++ b/internal/model/log_test.go @@ -29,7 +29,7 @@ func TestLogFullBuffer(t *testing.T) { data = append(data, "line"+strconv.Itoa(i)) m.Append(data[i]) } - m.Notify(false) + m.Notify(true) assert.Equal(t, 1, v.dataCalled) assert.Equal(t, 1, v.clearCalled) diff --git a/internal/view/log.go b/internal/view/log.go index db1c7c60..fdca9fc1 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -57,7 +57,6 @@ func NewLog(gvr client.GVR, path, co string, prev bool) *Log { // Init initialiazes the viewer. func (l *Log) Init(ctx context.Context) (err error) { - log.Debug().Msgf(">>> Logs INIT") if l.app, err = extractApp(ctx); err != nil { return err } @@ -235,9 +234,6 @@ func (l *Log) write(lines string) { // Flush write logs to viewer. func (l *Log) Flush(lines []string) { - if !l.indicator.AutoScroll() { - return - } l.write(strings.Join(lines, "\n")) l.indicator.Refresh() l.logs.ScrollToEnd() @@ -356,6 +352,11 @@ func (l *Log) textWrapCmd(*tcell.EventKey) *tcell.EventKey { // ToggleAutoScrollCmd toggles autoscroll status. func (l *Log) ToggleAutoScrollCmd(evt *tcell.EventKey) *tcell.EventKey { l.indicator.ToggleAutoScroll() + if l.indicator.AutoScroll() { + l.model.Start() + } else { + l.model.Stop() + } return nil } diff --git a/internal/view/log_test.go b/internal/view/log_test.go index 5e4fb84a..bb13df3b 100644 --- a/internal/view/log_test.go +++ b/internal/view/log_test.go @@ -34,11 +34,10 @@ func TestLogAutoScroll(t *testing.T) { v.GetModel().Set([]string{"blee", "bozo"}) v.GetModel().Notify(true) + assert.Equal(t, 6, len(v.Hints())) + v.ToggleAutoScrollCmd(nil) assert.Equal(t, " Autoscroll: Off FullScreen: Off Wrap: Off ", v.Indicator().GetText(true)) - v.ToggleAutoScrollCmd(nil) - assert.Equal(t, " Autoscroll: On FullScreen: Off Wrap: Off ", v.Indicator().GetText(true)) - assert.Equal(t, 6, len(v.Hints())) } func TestLogViewSave(t *testing.T) {