derailed 2020-02-02 09:23:22 -07:00
parent 5ebf196fc3
commit 9f36d29dc7
8 changed files with 78 additions and 32 deletions

View File

@ -0,0 +1,32 @@
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_small.png" align="right" width="200" height="auto"/>
# Release v0.13.7
## Notes
Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated!
Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM)
---
### GH Sponsorships
WOOT!! Big Thank you in this release to [Matthew Davis](https://github.com/mateothegreat) for your contributions and support for K9s!
Duly noted and so much appreciated!!
---
## Resolved Bugs/Features/PRs
* [Issue #520](https://github.com/derailed/k9s/issues/520)
* [Issue #518](https://github.com/derailed/k9s/issues/518)
* [Issue #517](https://github.com/derailed/k9s/issues/517)
* [Issue #516](https://github.com/derailed/k9s/issues/516)
* [Issue #506](https://github.com/derailed/k9s/issues/506)
---
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)

View File

@ -25,12 +25,14 @@ 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 {
checkClientSet *kubernetes.Clientset
client kubernetes.Interface client kubernetes.Interface
dClient dynamic.Interface dClient dynamic.Interface
nsClient dynamic.NamespaceableResourceInterface nsClient dynamic.NamespaceableResourceInterface
@ -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
} }
if _, err := client.ServerVersion(); err != nil { 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 := 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.

View File

@ -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

View File

@ -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())
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -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 {
if l.cancelFn != nil {
l.cancelFn() l.cancelFn()
}
close(c) close(c)
return err return err
} }
@ -155,7 +157,7 @@ func (l *Log) Append(line string) {
defer l.mx.Unlock() defer l.mx.Unlock()
if l.initialized { if l.initialized {
l.lines = []string{} l.lines, l.lastSent = []string{}, 0
l.initialized = false l.initialized = false
l.fireLogCleared() l.fireLogCleared()
} }
@ -175,7 +177,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)
} }
@ -224,6 +226,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

View File

@ -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)

View File

@ -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
} }

View File

@ -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) {