From c4fcecf7e78afb168459e84ed5222e213f6f8e67 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 29 Oct 2020 16:34:04 -0600 Subject: [PATCH] clean up and bugs fix --- .gitignore | 3 +- change_logs/release_v0.23.0.md | 54 +++++++++++++++++++++++++--------- cmd/root.go | 24 ++++++++------- go.mod | 6 ++-- go.sum | 7 +++++ internal/client/client.go | 16 +++++++++- internal/dao/registry.go | 2 +- internal/dao/table.go | 2 ++ internal/model/cluster.go | 26 ++++++++++++++-- internal/model/describe.go | 7 ++--- internal/model/yaml.go | 7 ++--- internal/render/pod_test.go | 4 +-- internal/ui/prompt.go | 4 ++- internal/view/app.go | 1 - internal/view/help.go | 4 +++ main.go | 3 ++ 16 files changed, 123 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index e3270627..2614fe70 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ dist notes vendor go.mod1 +go.mod2 gen.sh *.test *.log @@ -19,4 +20,4 @@ pod1.go faas .settings/* demos -/code \ No newline at end of file +/code diff --git a/change_logs/release_v0.23.0.md b/change_logs/release_v0.23.0.md index 247ca3c5..bbea4113 100644 --- a/change_logs/release_v0.23.0.md +++ b/change_logs/release_v0.23.0.md @@ -12,11 +12,14 @@ On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_inv --- -## ♫ Sound Behind The Release ♭ +## ♫ Sounds Behind The Release ♭ -I figured why not share one of the tunes I was spinning when powering thru teh bugs? Might as well share the pain/pleasure while viewing this release notes! +I figured why not share one of the tunes I was spinning when powering thru teh bugs? Might as well share the pain/pleasure while viewing these release notes! -[On An Island - David Gilmour With Crosby&Nash](https://www.youtube.com/watch?v=kEa__0wtIRo) +* [On An Island - David Gilmour With Crosby&Nash](https://www.youtube.com/watch?v=kEa__0wtIRo) +* [Cause We've Ended As Lovers - Jeff Beck](https://www.youtube.com/watch?v=VC02wGj5gPw) +* [La Maitresse D'Ecole - Maxime Le Forestier](https://www.youtube.com/watch?v=eE2-cv7taPo) +* [Three Wishes - Roger Waters](https://www.youtube.com/watch?v=fVw1N6wyo4c) ## Our Release Heroes... @@ -24,11 +27,11 @@ Please join me in recognizing and applauding this drop contributors that went th Big ATTA BOY/GIRL! in full effect this week to the good folks below for their efforts and contributions to K9s!! -* [Antoine Méausoone](https://github.com/Ameausoone) * [Michael Albers](https://github.com/michaeljohnalbers) * [Wi1dcard](https://github.com/wi1dcard) * [Saskia Keil](https://github.com/SaskiaKeil) * [Tomasz Lipinski](https://github.com/tlipinski) +* [Antoine Méausoone](https://github.com/Ameausoone) * [Emeric Martineau](https://github.com/emeric-martineau) * [Eldad Assis](https://github.com/eldada) * [David Arnold](https://github.com/blaggacao) @@ -45,29 +48,29 @@ First off I would like to send a `Big Thank You` to the following generous K9s f * [Matt Welke](https://github.com/mattwelke) * [Stefan Mikolajczyk](https://github.com/stefanmiko) -Contrarily to popular belief, OSS is not free! We've now reached ~9k stars and 300k downloads! As you all know, this project is not pimped out by a big company with deep pockets. K9s is complex and does demand lots of my time. So if this tool is useful to you and benefits you and your organization in your Kubernetes journey, please contribute! Your contribution whether financial, PRs, issues or shout-outs on social/blogs are crucial to keep K9s growing and powerful for all of us. Don't let OSS by individual contributors become an oxymoron! +Contrarily to popular belief, OSS is not free! We've now reached ~9k stars and 300k downloads! As you all know, this project is not pimped out by a big company with deep pockets and a big dev team. K9s is complex and does demand lots of my time. So if this tool is useful to you and your organization and part of your daily Kubernetes flow, please contribute! Your contribution whether financial, PRs, issues or shout-outs on social/blogs are crucial to keep K9s growing and powerful for all of us. Don't let OSS by individual contributors become an oxymoron! -## Describe/YAML views goes FullMonty +## Describe/YAML goes FullMonty!! -We've added a new option to enable full screen while describing or viewing a resource YAML. Similarly to the full screen toggle option in the log view, pressing `f` will now toggle fullscreen for both YAML and Describe views. +We've added a new option to enable full screen while describing or viewing a resource YAML. Similarly to the full screen toggle option in the log view, pressing `f` will now toggle full-screen for both YAML and Describe views. -Additionally, the YAML and Describe view are now reactive! YAML/Describe views will now watch for changes to the underlying resource manifests. How cool is that? +Additionally, the YAML and Describe view are now reactive! YAML/Describe views will now watch for changes to the underlying resource manifests. I'll admit this was a feature I was missing, but decided to punt as it required a bit of re-org to make it happen correctly. So BIG thanks to [Fabian-K](https://github.com/Fabian-K) for entering this issue and for the boost!! -Not cool enough for Ya? the YAML view also affords for getting ride of those pesky `managedFields` while viewing a resource. Pressing `m` will toggle visibility on these fields. +Not cool enough for Ya? the YAML view now also affords for getting ride of those pesky `managedFields` while viewing a resource. Use the `m` key to toggle visibility on the managedFields. ## Best Effort... Not! -In this drop, we've added 2 new columns to the Pod/Container views namely `CPU(R:L)` and `MEM(R:L)`. These represents the current request:limit resources specified at either the pod or container level. While in Pod view, you will need to use the `Go Wide` option `Ctrl-W` to see the resources set at the pod level. You can also leverage K9s [Custom Column](https://github.com/derailed/k9s#resource-custom-columns) feature to volunteer them while in Pod view. In the Container view these columns will be available by default. +In this drop, we've added 2 new columns namely `CPU/R:L` and `MEM/R:L`. These represents the current request:limit specified on containers. They are available in node, pod and container views. While in Pod view, you will need to volunteer them and use the `Go Wide` option `Ctrl-W` to see the columns. These columns will be display by default for Node/Container views. In the node view, they tally the total amount of resources for all pods hosted a given node. If that's inadequate, you can also leverage K9s [Custom Column](https://github.com/derailed/k9s#resource-custom-columns) feature to volunteer them or not. ## Set Container Images -You have now the ability to tweak your container images for experimentation, using the new SetImage binding aka `i`. This feature is available for unmanaged pods, deployments, sts and ds. With a resource selected, pressing `i` will provision an edit dialog listing all init/container images. +You will have the ability to tweak your container images for experimentation, using the new SetImage binding aka `i`. This feature is available for un-managed pods, deployments, statefulsets and daemonsets. With a resource selected, pressing `i` will provision an edit dialog listing all init/container images. So you will have to ability to tweak the images and update your containers. Big Thanks to [Antoine Méausoone](https://github.com/Ameausoone) for making this feature available to all of us!! NOTE! This is a one shot commands applied directly against your cluster and won't survive a new resource deployment. -## Crumbs On, Crumbs Off, Caterpillar +## Crumbs On...Crumbs Off, Caterpillar -We've added a new configuration to turn off the crumbs via `crumbsLess` configuration option. You can also toggle the crumbs via the new key option `C`. You can enable/disable this option in your ~/.k9s/config.yml or via command line using `--crumbsless` CLI option. +We've added a new configuCCration to turn off the crumbs via `crumbsLess` configuration option. You can also toggle the crumbs via the new key option `Ctrl-g`. You can enable/disable this option in your ~/.k9s/config.yml or via command line using `--crumbsless` CLI option. ```yaml k9s: @@ -80,7 +83,30 @@ k9s: ## BANG FILTERS! -Some folks have voiced the desire to use inverse filters to refine content while in resource table views. Prepending a `!` to your filter will now enable an inverse filtering operation For example, in order to see all pods that do not contain `fred` in their name, you can now use `/!fred` as your filtering command. +Some folks have voiced the desire to use inverse filters to refine content while in resource table views. Appending a `!` to your filter will now enable an inverse filtering operation For example, in order to see all pods that do not contain `fred` in their name, you can now use `/!fred` as your filtering command. If you dig this implementation, please make sure to give a big thank you to [Michael Albers](https://github.com/michaeljohnalbers) for the swift implementation! + +## New Conf On the Block... + +In this release, we've made some changes to the retry policies when things fail on your cluster and the api-server is suffering from an hearing impediment. The current policy was to check for connection issues every 15secs and retry 15 times before exiting K9s. This rules were not configurable and could yield for overtaxing the api-server. So we've implemented exponential back-off so that K9s can attempt to remediate or bail out of the session if not. +To this end, there is a new config option namely `maxConnRetry` to will be added to your K9s config to set the retry policy. The default is currently set to 5 retries. + +NOTE: This is likely an ongoing story and more will come based on your feedback! + +Sample K9s configuration + +```yaml +k9s: + refreshRate: 2 + # Set the maximum attempt to reconnect with the api-server in case of failures. + maxConnRetry: 5 + ... +``` + +## And That's A Wrap! + +As you can see, this is a pretty big drop and likely we've created some new issues in the process. Please make sure to file issues/PRs if things are not working as expected so we can improve on these features. + +Thank you all for your continued excitement and support for K9s! --- diff --git a/cmd/root.go b/cmd/root.go index f4987e21..18ac5890 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -3,7 +3,6 @@ package cmd import ( "flag" "fmt" - "io/ioutil" "runtime/debug" "github.com/derailed/k9s/internal/client" @@ -45,17 +44,22 @@ func init() { initK9sFlags() initK8sFlags() - // Klogs (of course) want to print stuff to the screen ;( - klog.InitFlags(nil) - klog.SetOutput(ioutil.Discard) - if err := flag.Set("stderrthreshold", "fatal"); err != nil { - log.Error().Err(err) + var flags flag.FlagSet + klog.InitFlags(&flags) + if err := flags.Set("logtostderr", "false"); err != nil { + panic(err) } - if err := flag.Set("alsologtostderr", "false"); err != nil { - log.Error().Err(err) + if err := flags.Set("alsologtostderr", "false"); err != nil { + panic(err) } - if err := flag.Set("logtostderr", "false"); err != nil { - log.Error().Err(err) + if err := flags.Set("stderrthreshold", "fatal"); err != nil { + panic(err) + } + if err := flags.Set("v", "0"); err != nil { + panic(err) + } + if err := flags.Set("log_file", config.K9sLogs); err != nil { + panic(err) } } diff --git a/go.mod b/go.mod index 1cc8c3b7..e795fa52 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/derailed/tview v0.4.6 github.com/drone/envsubst v1.0.2 // indirect github.com/fatih/color v1.9.0 - github.com/fsnotify/fsnotify v1.4.7 - github.com/fvbommel/sortorder v1.0.1 - github.com/gdamore/tcell v1.3.0 + github.com/fsnotify/fsnotify v1.4.9 + github.com/fvbommel/sortorder v1.0.2 + github.com/gdamore/tcell v1.4.0 github.com/ghodss/yaml v1.0.0 github.com/golang/protobuf v1.4.2 // indirect github.com/kylelemons/godebug v1.1.0 // indirect diff --git a/go.sum b/go.sum index 72b70c82..66ba659f 100644 --- a/go.sum +++ b/go.sum @@ -229,6 +229,8 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM45eo= +github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= @@ -236,6 +238,8 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo github.com/gdamore/tcell v1.1.2/go.mod h1:h3kq4HO9l2On+V9ed8w8ewqQEmGCSSHOgQ+2h8uzurE= github.com/gdamore/tcell v1.3.0 h1:r35w0JBADPZCVQijYebl6YMWWtHRqVEGt7kL2eBADRM= github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= +github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU= +github.com/gdamore/tcell v1.4.0/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -463,6 +467,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9 github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= +github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= +github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -485,6 +491,7 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.5/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= diff --git a/internal/client/client.go b/internal/client/client.go index db4322ab..da7b35cf 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -179,13 +179,27 @@ func (a *APIClient) CurrentNamespaceName() (string, error) { return a.config.CurrentNamespaceName() } +const serverVersion = "serverVersion" + // ServerVersion returns the current server version info. func (a *APIClient) ServerVersion() (*version.Info, error) { + if v, ok := a.cache.Get(serverVersion); ok { + if version, ok := v.(*version.Info); ok { + return version, nil + } + } dial, err := a.CachedDiscovery() if err != nil { return nil, err } - return dial.ServerVersion() + + info, err := dial.ServerVersion() + if err != nil { + return nil, err + } + a.cache.Add(serverVersion, info, cacheExpiry) + + return info, nil } // ValidNamespaces returns all available namespaces. diff --git a/internal/dao/registry.go b/internal/dao/registry.go index 0728d941..4742c819 100644 --- a/internal/dao/registry.go +++ b/internal/dao/registry.go @@ -57,7 +57,7 @@ func AccessorFor(f Factory, gvr client.GVR) (Accessor, error) { r, ok := m[gvr] if !ok { r = &Generic{} - log.Debug().Msgf("No DAO registry entry for %q. Using factory!", gvr) + log.Debug().Msgf("No DAO registry entry for %q. Using generics!", gvr) } r.Init(f, gvr) diff --git a/internal/dao/table.go b/internal/dao/table.go index 772eae03..422ccddd 100644 --- a/internal/dao/table.go +++ b/internal/dao/table.go @@ -13,6 +13,8 @@ import ( "k8s.io/client-go/rest" ) +// BOZO!! Figure out how to convert to table def and use factory. + // Table retrieves K8s resources as tabular data. type Table struct { Generic diff --git a/internal/model/cluster.go b/internal/model/cluster.go index 94d4c726..fe7beca5 100644 --- a/internal/model/cluster.go +++ b/internal/model/cluster.go @@ -2,13 +2,21 @@ package model import ( "context" + "time" "github.com/derailed/k9s/internal/client" "github.com/derailed/k9s/internal/dao" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/cache" mv1beta1 "k8s.io/metrics/pkg/apis/metrics/v1beta1" ) +const ( + clusterCacheSize = 100 + clusterCacheExpiry = 1 * time.Minute + clusterNodesKey = "nodes" +) + type ( // MetricsServer gather metrics information from pods and nodes. MetricsServer interface { @@ -30,6 +38,7 @@ type ( Cluster struct { factory dao.Factory mx MetricsServer + cache *cache.LRUExpireCache } ) @@ -38,6 +47,7 @@ func NewCluster(f dao.Factory) *Cluster { return &Cluster{ factory: f, mx: client.DialMetrics(f.Client()), + cache: cache.NewLRUExpireCache(clusterCacheSize), } } @@ -80,11 +90,21 @@ func (c *Cluster) UserName() string { // Metrics gathers node level metrics and compute utilization percentages. func (c *Cluster) Metrics(ctx context.Context, mx *client.ClusterMetrics) error { - nn, err := dao.FetchNodes(ctx, c.factory, "") - if err != nil { - return err + var nn *v1.NodeList + if n, ok := c.cache.Get(clusterNodesKey); ok { + if nodes, ok := n.(*v1.NodeList); ok { + nn = nodes + } } + var err error + if nn == nil { + nn, err = dao.FetchNodes(ctx, c.factory, "") + if err != nil { + return err + } + } + c.cache.Add(clusterNodesKey, nn, clusterCacheExpiry) nmx, err := c.mx.FetchNodesMetrics(ctx) if err != nil { return err diff --git a/internal/model/describe.go b/internal/model/describe.go index 0e7bcad0..51386d74 100644 --- a/internal/model/describe.go +++ b/internal/model/describe.go @@ -124,11 +124,9 @@ func (d *Describe) updater(ctx context.Context) { return case <-time.After(delay): if err := d.refresh(ctx); err != nil { - log.Error().Err(err).Msgf("Describe Failed") d.fireResourceFailed(err) - delay = backOff.NextBackOff() - if delay == backoff.Stop { - log.Error().Err(err).Msgf("Describe done Retrying bailing out!") + if delay = backOff.NextBackOff(); delay == backoff.Stop { + log.Error().Err(err).Msgf("Describe gave up!") return } } else { @@ -139,7 +137,6 @@ func (d *Describe) updater(ctx context.Context) { } } func (d *Describe) refresh(ctx context.Context) error { - log.Debug().Msgf("DESCRefresh %v", time.Now()) if !atomic.CompareAndSwapInt32(&d.inUpdate, 0, 1) { log.Debug().Msgf("Dropping update...") return nil diff --git a/internal/model/yaml.go b/internal/model/yaml.go index f979e418..9870e802 100644 --- a/internal/model/yaml.go +++ b/internal/model/yaml.go @@ -135,11 +135,9 @@ func (y *YAML) updater(ctx context.Context) { return case <-time.After(delay): if err := y.refresh(ctx); err != nil { - log.Error().Err(err).Msgf("YAML Failed") y.fireResourceFailed(err) - delay = backOff.NextBackOff() - if delay == backoff.Stop { - log.Error().Err(err).Msgf("YAML done Retrying bailing out!") + if delay = backOff.NextBackOff(); delay == backoff.Stop { + log.Error().Err(err).Msgf("YAML gave up!") return } } else { @@ -151,7 +149,6 @@ func (y *YAML) updater(ctx context.Context) { } func (y *YAML) refresh(ctx context.Context) error { - log.Debug().Msgf("YAMLRefresh %v", time.Now()) if !atomic.CompareAndSwapInt32(&y.inUpdate, 0, 1) { log.Debug().Msgf("Dropping update...") return nil diff --git a/internal/render/pod_test.go b/internal/render/pod_test.go index 5e75ad17..d32ff59c 100644 --- a/internal/render/pod_test.go +++ b/internal/render/pod_test.go @@ -150,7 +150,7 @@ func TestPodColorer(t *testing.T) { func TestPodRender(t *testing.T) { pom := render.PodWithMetrics{ Raw: load(t, "po"), - MX: makePodMX("nginx", "10m", "10Mi"), + MX: makePodMX("nginx", "100m", "50Mi"), } var po render.Pod @@ -159,7 +159,7 @@ func TestPodRender(t *testing.T) { assert.Nil(t, err) assert.Equal(t, "default/nginx", r.ID) - e := render.Fields{"default", "nginx", "●", "1/1", "0", "Running", "10", "10", "100:0", "70:170", "10", "0", "14", "5", "172.17.0.6", "minikube", "BE"} + e := render.Fields{"default", "nginx", "●", "1/1", "0", "Running", "100", "50", "100:0", "70:170", "100", "0", "71", "29", "172.17.0.6", "minikube", "BE"} assert.Equal(t, e, r.Fields[:17]) } diff --git a/internal/ui/prompt.go b/internal/ui/prompt.go index 48720796..9ff081b5 100644 --- a/internal/ui/prompt.go +++ b/internal/ui/prompt.go @@ -204,7 +204,9 @@ func (p *Prompt) write(text, suggest string) { // Event Listener protocol... // BufferCompleted indicates input was accepted. -func (p *Prompt) BufferCompleted(s string) {} +func (p *Prompt) BufferCompleted(s string) { + p.update(s) +} // BufferChanged indicates the buffer was changed. func (p *Prompt) BufferChanged(s string) { diff --git a/internal/view/app.go b/internal/view/app.go index 8dedb4d2..3a8ded39 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -302,7 +302,6 @@ func (a *App) clusterUpdater(ctx context.Context) { } func (a *App) refreshCluster() error { - log.Debug().Msgf("Cluster Refresh %v", time.Now()) c := a.Content.Top() if ok := a.Conn().CheckConnectivity(); ok { if atomic.LoadInt32(&a.conRetry) > 0 { diff --git a/internal/view/help.go b/internal/view/help.go index bfc39499..460dfd62 100644 --- a/internal/view/help.go +++ b/internal/view/help.go @@ -238,6 +238,10 @@ func (h *Help) showGeneral() model.MenuHints { Mnemonic: "Ctrl-e", Description: "Toggle Header", }, + { + Mnemonic: "Ctrl-g", + Description: "Toggle Crumbs", + }, { Mnemonic: ":q", Description: "Quit", diff --git a/main.go b/main.go index a040a539..69ab6697 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,9 @@ func init() { func main() { mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod) + defer func() { + _ = file.Close() + }() if err != nil { panic(err) }