diff --git a/Dockerfile b/Dockerfile index 4342f7dd..002059f6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build... -FROM golang:1.14.1-alpine3.11 AS build +FROM golang:1.14.4-alpine3.11 AS build WORKDIR /k9s COPY go.mod go.sum main.go Makefile ./ diff --git a/Makefile b/Makefile index 78bbbdaa..94193d12 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ PACKAGE := github.com/derailed/$(NAME) GIT := $(shell git rev-parse --short HEAD) SOURCE_DATE_EPOCH ?= $(shell date +%s) DATE := $(shell date -u -d @${SOURCE_DATE_EPOCH} +%FT%T%Z) -VERSION ?= v0.20.3 +VERSION ?= v0.21.2 IMG_NAME := derailed/k9s IMAGE := ${IMG_NAME}:${VERSION} diff --git a/go.mod b/go.mod index a5383e4b..81a271d7 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/derailed/k9s go 1.14 +replace github.com/derailed/tview => /Users/fernand/go_wk/derailed/src/github.com/derailed/tview + require ( 9fans.net/go v0.0.2 github.com/atotto/clipboard v0.1.2 diff --git a/internal/dao/pod.go b/internal/dao/pod.go index b03dabeb..acc7232b 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -356,7 +356,7 @@ func readLogs(stream io.ReadCloser, c LogChan, opts LogOptions) { return } log.Warn().Err(err).Msgf("Stream READ error %s", opts.Info()) - c <- opts.DecorateLog([]byte("log stream failed\n")) + c <- opts.DecorateLog([]byte(fmt.Sprintf("log stream failed: %#v\n", err))) return } c <- opts.DecorateLog(bytes) diff --git a/internal/ui/app.go b/internal/ui/app.go index d76bba25..765581f7 100644 --- a/internal/ui/app.go +++ b/internal/ui/app.go @@ -1,6 +1,8 @@ package ui import ( + "sync" + "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/model" @@ -19,6 +21,8 @@ type App struct { actions KeyActions views map[string]tview.Primitive cmdModel *model.FishBuff + running bool + mx sync.RWMutex } // NewApp returns a new app. @@ -53,6 +57,18 @@ func (a *App) Init() { a.SetRoot(a.Main, true) } +func (a *App) IsRunning() bool { + a.mx.RLock() + defer a.mx.RUnlock() + return a.running +} + +func (a *App) SetRunning(f bool) { + a.mx.Lock() + defer a.mx.Unlock() + a.running = f +} + // BufferChanged indicates the buffer was changed. func (a *App) BufferChanged(s string) {} @@ -69,7 +85,8 @@ func (a *App) BufferActive(state bool, kind model.BufferKind) { flex.RemoveItemAtIndex(1) a.SetFocus(flex) } - a.Draw() + // BOZO!! + //a.Draw() } // SuggestionChanged notifies of update to command suggestions. diff --git a/internal/ui/flash.go b/internal/ui/flash.go index 82abf53b..28991190 100644 --- a/internal/ui/flash.go +++ b/internal/ui/flash.go @@ -65,6 +65,9 @@ func (f *Flash) Watch(ctx context.Context, c model.FlashChan) { // SetMessage sets flash message and level. func (f *Flash) SetMessage(m model.LevelMessage) { + if !f.app.IsRunning() { + return + } fn := func() { if m.Text == "" { f.Clear() @@ -76,9 +79,11 @@ func (f *Flash) SetMessage(m model.LevelMessage) { if f.testMode { fn() - } else { - f.app.QueueUpdateDraw(fn) } + // BOZO!! + //} else { + // f.app.QueueUpdate(fn) + //} } func (f *Flash) flashEmoji(l model.FlashLevel) string { diff --git a/internal/ui/indicator.go b/internal/ui/indicator.go index c144689a..36b9081e 100644 --- a/internal/ui/indicator.go +++ b/internal/ui/indicator.go @@ -64,6 +64,9 @@ func (s *StatusIndicator) ClusterInfoUpdated(data model.ClusterMeta) { // ClusterInfoChanged notifies the cluster meta was changed. func (s *StatusIndicator) ClusterInfoChanged(prev, cur model.ClusterMeta) { + if !s.app.IsRunning() { + return + } s.app.QueueUpdateDraw(func() { s.SetPermanent(fmt.Sprintf( statusIndicatorFmt, diff --git a/internal/view/app.go b/internal/view/app.go index 27c6cad0..67b97350 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -421,6 +421,7 @@ func (a *App) Run() error { if err := a.command.defaultCmd(); err != nil { return err } + a.SetRunning(true) if err := a.Application.Run(); err != nil { return err } @@ -446,12 +447,13 @@ func (a *App) IsBenchmarking() bool { // ClearStatus reset logo back to normal. func (a *App) ClearStatus(flash bool) { - a.QueueUpdateDraw(func() { - a.Logo().Reset() - if flash { - a.Flash().Clear() - } - }) + // BOZO!! + //a.QueueUpdate(func() { + a.Logo().Reset() + if flash { + a.Flash().Clear() + } + //}) } func (a *App) setLogo(l model.FlashLevel, msg string) { diff --git a/internal/view/browser.go b/internal/view/browser.go index 699e2a39..335bc6ec 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -57,7 +57,9 @@ func (b *Browser) Init(ctx context.Context) error { return e } } - b.app.CmdBuff().Reset() + if b.App().IsRunning() { + b.app.CmdBuff().Reset() + } b.bindKeys() if b.bindKeysFn != nil { @@ -200,14 +202,16 @@ func (b *Browser) Aliases() []string { // TableDataChanged notifies view new data is available. func (b *Browser) TableDataChanged(data render.TableData) { - if !b.app.ConOK() || b.cancelFn == nil { + if !b.app.ConOK() || b.cancelFn == nil || !b.app.IsRunning() { return } - b.app.QueueUpdateDraw(func() { + //BOZO!! + b.app.QueueUpdate(func() { b.refreshActions() b.Update(data) }) + //b.app.Draw() } // TableLoadFailed notifies view something went south. diff --git a/internal/view/cluster_info.go b/internal/view/cluster_info.go index b686209f..59760ae5 100644 --- a/internal/view/cluster_info.go +++ b/internal/view/cluster_info.go @@ -85,21 +85,25 @@ func (c *ClusterInfo) ClusterInfoUpdated(data model.ClusterMeta) { // ClusterInfoChanged notifies the cluster meta was changed. func (c *ClusterInfo) ClusterInfoChanged(prev, curr model.ClusterMeta) { - c.app.QueueUpdate(func() { - c.Clear() - c.layout() - row := c.setCell(0, curr.Context) - row = c.setCell(row, curr.Cluster) - row = c.setCell(row, curr.User) - row = c.setCell(row, fmt.Sprintf("%s [%d]", curr.K9sVer, os.Getpid())) - row = c.setCell(row, curr.K8sVer) - if c.app.Conn().HasMetrics() { - row = c.setCell(row, ui.AsPercDelta(prev.Cpu, curr.Cpu)) - _ = c.setCell(row, ui.AsPercDelta(prev.Mem, curr.Mem)) - c.setDefCon(curr.Cpu, curr.Mem) - } - c.updateStyle() - }) + if !c.app.IsRunning() { + return + } + // BOZO!! + //c.app.QueueUpdate(func() { + c.Clear() + c.layout() + row := c.setCell(0, curr.Context) + row = c.setCell(row, curr.Cluster) + row = c.setCell(row, curr.User) + row = c.setCell(row, fmt.Sprintf("%s [%d]", curr.K9sVer, os.Getpid())) + row = c.setCell(row, curr.K8sVer) + if c.app.Conn().HasMetrics() { + row = c.setCell(row, ui.AsPercDelta(prev.Cpu, curr.Cpu)) + _ = c.setCell(row, ui.AsPercDelta(prev.Mem, curr.Mem)) + c.setDefCon(curr.Cpu, curr.Mem) + } + c.updateStyle() + //}) } const defconFmt = "%s %s level!" diff --git a/internal/view/log.go b/internal/view/log.go index cf4a854f..9894b1ab 100644 --- a/internal/view/log.go +++ b/internal/view/log.go @@ -116,13 +116,15 @@ func (l *Log) LogFailed(err error) { if l.logs.GetText(true) == logMessage { l.logs.Clear() } - fmt.Fprintln(l.ansiWriter, tview.Escape(color.Colorize(err.Error(), color.Red))) + if _, err = l.ansiWriter.Write([]byte(tview.Escape(color.Colorize(err.Error(), color.Red)))); err != nil { + log.Error().Err(err).Msgf("Writing log error") + } }) } // LogChanged updates the logs. func (l *Log) LogChanged(lines dao.LogItems) { - l.app.QueueUpdateDraw(func() { + l.app.QueueUpdate(func() { l.Flush(lines) }) } @@ -247,13 +249,19 @@ var EOL = []byte{'\n'} // Flush write logs to viewer. func (l *Log) Flush(lines dao.LogItems) { + log.Debug().Msgf("Flush %d", len(lines)) ll := make([][]byte, len(lines)) + log.Debug().Msgf("A") lines.Render(l.Indicator().showTime, ll) + log.Debug().Msgf("A") _, _ = l.ansiWriter.Write(EOL) + log.Debug().Msgf("A") if _, err := l.ansiWriter.Write(bytes.Join(ll, EOL)); err != nil { log.Error().Err(err).Msgf("write logs failed") } + log.Debug().Msgf("A") l.logs.ScrollToEnd() + log.Debug().Msgf("A") l.indicator.Refresh() }