From d0f874e01a747d8851f0751e2fd7677266733f7f Mon Sep 17 00:00:00 2001 From: Fernand Galiana Date: Wed, 3 Jan 2024 12:07:02 -0700 Subject: [PATCH] K9s/release v0.30.8 (#2427) * [Bug] Fix #2418 * cleaning up * rel notes --- Makefile | 2 +- change_logs/release_v0.30.8.md | 48 +++++++++++++++++++++++++++++++++ internal/config/data/context.go | 2 +- internal/config/data/ns.go | 13 ++++----- internal/config/data/ns_test.go | 8 +++--- internal/config/k9s.go | 14 +++++++--- internal/config/logger.go | 7 +---- internal/config/logger_test.go | 4 +-- internal/config/shell_pod.go | 4 +-- internal/config/styles.go | 4 --- internal/config/threshold.go | 7 +---- internal/ui/config.go | 9 +++---- internal/view/exec.go | 24 ++++++++++++----- snap/snapcraft.yaml | 2 +- 14 files changed, 99 insertions(+), 49 deletions(-) create mode 100644 change_logs/release_v0.30.8.md diff --git a/Makefile b/Makefile index c2639ec4..7add385c 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ DATE ?= $(shell TZ=UTC date -j -f "%s" ${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H: else DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ") endif -VERSION ?= v0.30.7 +VERSION ?= v0.30.8 IMG_NAME := derailed/k9s IMAGE := ${IMG_NAME}:${VERSION} diff --git a/change_logs/release_v0.30.8.md b/change_logs/release_v0.30.8.md new file mode 100644 index 00000000..f76143f3 --- /dev/null +++ b/change_logs/release_v0.30.8.md @@ -0,0 +1,48 @@ + + +# Release v0.30.8 + +## 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 are, as ever, very much noted and appreciated! +Also big thanks to all that have allocated their own time to help others on both slack and on this repo!! + +As you may know, K9s is not pimped out by corps with deep pockets, thus if you feel K9s is helping your Kubernetes journey, +please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or 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) + +## Maintenance Release! + +Thank you all for pitching in and helping flesh out issues!! + +--- + +## Videos Are In The Can! + +Please dial [K9s Channel](https://www.youtube.com/channel/UC897uwPygni4QIjkPCpgjmw) for up coming content... + +* [K9s v0.30.0 Sneak peek](https://youtu.be/mVBc1XneRJ4) +* [Vulnerability Scans](https://youtu.be/ULkl0MsaidU) + +--- + +## Resolved Issues + +* [#2423](https://github.com/derailed/k9s/issues/2423) CPU and MEM counters of AKS clusters show not available +* [#2418](https://github.com/derailed/k9s/issues/2418) Boom! runtime error: invalid memory address or nil pointer dereference + +--- + +## Contributed PRs + +Please be sure to give `Big Thanks!` and `ATTA Girls/Boys!` to all the fine contributors for making K9s better for all of us!! + +* [#2424](https://github.com/derailed/k9s/pull/2424) fix the check for whether the cluster supports metrics + + © 2023 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/internal/config/data/context.go b/internal/config/data/context.go index 081b1338..8f38676e 100644 --- a/internal/config/data/context.go +++ b/internal/config/data/context.go @@ -54,7 +54,7 @@ func (c *Context) Validate(conn client.Connection, ks KubeSettings) { if c.Namespace == nil { c.Namespace = NewNamespace() } - c.Namespace.Validate(conn, ks) + c.Namespace.Validate(conn) if c.View == nil { c.View = NewView() diff --git a/internal/config/data/ns.go b/internal/config/data/ns.go index 69ab9cd5..ba8aacae 100644 --- a/internal/config/data/ns.go +++ b/internal/config/data/ns.go @@ -22,10 +22,7 @@ type Namespace struct { // NewNamespace create a new namespace configuration. func NewNamespace() *Namespace { - return &Namespace{ - Active: client.DefaultNamespace, - Favorites: []string{client.DefaultNamespace}, - } + return NewActiveNamespace(client.DefaultNamespace) } func NewActiveNamespace(n string) *Namespace { @@ -39,7 +36,7 @@ func NewActiveNamespace(n string) *Namespace { } // Validate validates a namespace is setup correctly. -func (n *Namespace) Validate(c client.Connection, ks KubeSettings) { +func (n *Namespace) Validate(c client.Connection) { if c == nil || !c.IsValidNamespace(n.Active) { return } @@ -56,7 +53,11 @@ func (n *Namespace) SetActive(ns string, ks KubeSettings) error { if ns == client.BlankNamespace { ns = client.NamespaceAll } - n.Active = ns + if n == nil { + n = NewActiveNamespace(ns) + } else { + n.Active = ns + } if ns != "" && !n.LockFavorites { n.addFavNS(ns) } diff --git a/internal/config/data/ns_test.go b/internal/config/data/ns_test.go index 7a45ead5..d66b6903 100644 --- a/internal/config/data/ns_test.go +++ b/internal/config/data/ns_test.go @@ -13,7 +13,7 @@ import ( func TestNSValidate(t *testing.T) { ns := data.NewNamespace() - ns.Validate(mock.NewMockConnection(), mock.NewMockKubeSettings(makeFlags("cl-1", "ct-1"))) + ns.Validate(mock.NewMockConnection()) assert.Equal(t, "default", ns.Active) assert.Equal(t, []string{"default"}, ns.Favorites) @@ -21,7 +21,7 @@ func TestNSValidate(t *testing.T) { func TestNSValidateMissing(t *testing.T) { ns := data.NewNamespace() - ns.Validate(mock.NewMockConnection(), mock.NewMockKubeSettings(makeFlags("cl-1", "ct-1"))) + ns.Validate(mock.NewMockConnection()) assert.Equal(t, "default", ns.Active) assert.Equal(t, []string{"default"}, ns.Favorites) @@ -29,7 +29,7 @@ func TestNSValidateMissing(t *testing.T) { func TestNSValidateNoNS(t *testing.T) { ns := data.NewNamespace() - ns.Validate(mock.NewMockConnection(), mock.NewMockKubeSettings(makeFlags("cl-1", "ct-1"))) + ns.Validate(mock.NewMockConnection()) assert.Equal(t, "default", ns.Active) assert.Equal(t, []string{"default"}, ns.Favorites) @@ -61,7 +61,7 @@ func TestNSSetActive(t *testing.T) { func TestNSValidateRmFavs(t *testing.T) { ns := data.NewNamespace() ns.Favorites = []string{"default", "fred"} - ns.Validate(mock.NewMockConnection(), mock.NewMockKubeSettings(makeFlags("cl-1", "ct-1"))) + ns.Validate(mock.NewMockConnection()) assert.Equal(t, []string{"default", "fred"}, ns.Favorites) } diff --git a/internal/config/k9s.go b/internal/config/k9s.go index decac450..69e4ddd5 100644 --- a/internal/config/k9s.go +++ b/internal/config/k9s.go @@ -163,6 +163,13 @@ func (k *K9s) ActiveContextName() string { // ActiveContext returns the currently active context. func (k *K9s) ActiveContext() (*data.Context, error) { if k.activeConfig != nil { + if k.activeConfig.Context == nil { + ct, err := k.ks.CurrentContext() + if err != nil { + return nil, err + } + k.activeConfig.Context = data.NewContextFromConfig(ct) + } return k.activeConfig.Context, nil } @@ -187,6 +194,7 @@ func (k *K9s) ActivateContext(n string) (*data.Context, error) { } // If the context specifies a default namespace, use it! if k.conn != nil { + k.Validate(k.conn, k.ks) if ns := k.conn.ActiveNamespace(); ns != client.BlankNamespace { k.activeConfig.Context.Namespace.Active = ns } else { @@ -328,17 +336,17 @@ func (k *K9s) Validate(c client.Connection, ks data.KubeSettings) { if k.ShellPod == nil { k.ShellPod = NewShellPod() } - k.ShellPod.Validate(c, ks) + k.ShellPod.Validate() if k.Logger == nil { k.Logger = NewLogger() } else { - k.Logger.Validate(c, ks) + k.Logger.Validate() } if k.Thresholds == nil { k.Thresholds = NewThreshold() } - k.Thresholds.Validate(c, ks) + k.Thresholds.Validate() if k.activeConfig != nil { k.activeConfig.Validate(c, ks) diff --git a/internal/config/logger.go b/internal/config/logger.go index 4cca7e97..014d724c 100644 --- a/internal/config/logger.go +++ b/internal/config/logger.go @@ -3,11 +3,6 @@ package config -import ( - "github.com/derailed/k9s/internal/client" - "github.com/derailed/k9s/internal/config/data" -) - const ( // DefaultLoggerTailCount tracks default log tail size. DefaultLoggerTailCount = 100 @@ -39,7 +34,7 @@ func NewLogger() *Logger { } // Validate checks thresholds and make sure we're cool. If not use defaults. -func (l *Logger) Validate(_ client.Connection, _ data.KubeSettings) { +func (l *Logger) Validate() { if l.TailCount <= 0 { l.TailCount = DefaultLoggerTailCount } diff --git a/internal/config/logger_test.go b/internal/config/logger_test.go index e0253505..51625df6 100644 --- a/internal/config/logger_test.go +++ b/internal/config/logger_test.go @@ -12,7 +12,7 @@ import ( func TestNewLogger(t *testing.T) { l := config.NewLogger() - l.Validate(nil, nil) + l.Validate() assert.Equal(t, int64(100), l.TailCount) assert.Equal(t, 5000, l.BufferSize) @@ -20,7 +20,7 @@ func TestNewLogger(t *testing.T) { func TestLoggerValidate(t *testing.T) { var l config.Logger - l.Validate(nil, nil) + l.Validate() assert.Equal(t, int64(100), l.TailCount) assert.Equal(t, 5000, l.BufferSize) diff --git a/internal/config/shell_pod.go b/internal/config/shell_pod.go index 19ad05a0..c431bc1b 100644 --- a/internal/config/shell_pod.go +++ b/internal/config/shell_pod.go @@ -4,8 +4,6 @@ package config import ( - "github.com/derailed/k9s/internal/client" - "github.com/derailed/k9s/internal/config/data" v1 "k8s.io/api/core/v1" ) @@ -37,7 +35,7 @@ func NewShellPod() *ShellPod { } // Validate validates the configuration. -func (s *ShellPod) Validate(client.Connection, data.KubeSettings) { +func (s *ShellPod) Validate() { if s.Image == "" { s.Image = defaultDockerShellImage } diff --git a/internal/config/styles.go b/internal/config/styles.go index 5dd3c099..06690d7d 100644 --- a/internal/config/styles.go +++ b/internal/config/styles.go @@ -445,10 +445,6 @@ func (s *Styles) Reset() { s.K9s = newStyle() } -// DefaultSkin loads the default skin. -func (s *Styles) DefaultSkin() { -} - // FgColor returns the foreground color. func (s *Styles) FgColor() tcell.Color { return s.Body().FgColor.Color() diff --git a/internal/config/threshold.go b/internal/config/threshold.go index f15bd8c1..e7467755 100644 --- a/internal/config/threshold.go +++ b/internal/config/threshold.go @@ -3,11 +3,6 @@ package config -import ( - "github.com/derailed/k9s/internal/client" - "github.com/derailed/k9s/internal/config/data" -) - const ( // SeverityLow tracks low severity. SeverityLow SeverityLevel = iota @@ -66,7 +61,7 @@ func NewThreshold() Threshold { } // Validate a namespace is setup correctly. -func (t Threshold) Validate(c client.Connection, ks data.KubeSettings) { +func (t Threshold) Validate() { for _, k := range []string{"cpu", "memory"} { v, ok := t[k] if !ok { diff --git a/internal/ui/config.go b/internal/ui/config.go index 1ddb04f1..4509280c 100644 --- a/internal/ui/config.go +++ b/internal/ui/config.go @@ -211,12 +211,12 @@ func (c *Configurator) activeConfig() (cluster string, context string, ok bool) func (c *Configurator) RefreshStyles() { if c.Styles == nil { c.Styles = config.NewStyles() - } else { - c.Styles.Reset() } cl, ct, ok := c.activeConfig() if !ok { + log.Debug().Msgf("No custom skin found. Using stock skin") + c.updateStyles("") return } @@ -228,7 +228,7 @@ func (c *Configurator) RefreshStyles() { skin, ok := c.activeSkin() if !ok { - log.Debug().Msgf("No custom skin found. Loading default") + log.Debug().Msgf("No custom skin found. Using stock skin") c.updateStyles("") return } @@ -248,9 +248,6 @@ func (c *Configurator) RefreshStyles() { func (c *Configurator) updateStyles(f string) { c.skinFile = f - if !c.HasSkin() { - c.Styles.DefaultSkin() - } c.Styles.Update() render.ModColor = c.Styles.Frame().Status.ModifyColor.Color() diff --git a/internal/view/exec.go b/internal/view/exec.go index effe8c95..97d0dc53 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -38,6 +38,8 @@ const ( bannerFmt = "<> Pod: %s | Container: %s \n" ) +var editorEnvVars = []string{"KUBE_EDITOR", "K9S_EDITOR", "EDITOR"} + type shellOpts struct { clear, background bool pipes []string @@ -115,13 +117,23 @@ func run(a *App, opts shellOpts) (bool, chan error, chan string) { } func edit(a *App, opts shellOpts) bool { - bin, err := exec.LookPath(os.Getenv("K9S_EDITOR")) - if err != nil { - bin, err = exec.LookPath(os.Getenv("EDITOR")) - if err != nil { - log.Error().Err(err).Msgf("K9S_EDITOR|EDITOR not set") - return false + var ( + bin string + err error + ) + for _, e := range editorEnvVars { + env := os.Getenv(e) + if env != "" { + continue } + bin, err = exec.LookPath(env) + if err != nil { + continue + } + } + if bin == "" { + a.Flash().Errf("You must set at least one of those env vars: %s", strings.Join(editorEnvVars, "|")) + return false } opts.binary, opts.background = bin, false diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7515aa75..2b3acfe1 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: k9s base: core20 -version: 'v0.30.7' +version: 'v0.30.8' summary: K9s is a CLI to view and manage your Kubernetes clusters. description: | K9s is a CLI to view and manage your Kubernetes clusters. By leveraging a terminal UI, you can easily traverse Kubernetes resources and view the state of your clusters in a single powerful session.