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