From 1d8cb6ced0d0f1231fa6bd59f165277d7416b736 Mon Sep 17 00:00:00 2001 From: Fernand Galiana Date: Sat, 27 Sep 2025 09:16:36 -0600 Subject: [PATCH] Rel v0.50.13 (#3592) * fix #3587 - dp restart * fix #3585 - sec abreviation * fix #3583 - exec without node read * fix #3574 - label filter path * fix #3584 - managed fields * fix #3577 - pod logs * rel notes --- Makefile | 2 +- change_logs/release_v0.50.13.md | 32 ++++++++++++++++++++++++++++++++ internal/client/gvr.go | 2 +- internal/config/alias.go | 6 +++++- internal/dao/helpers.go | 14 ++++---------- internal/dao/pod.go | 4 ++-- internal/render/dp.go | 2 +- internal/render/sts.go | 18 +++++++++++------- internal/view/exec.go | 2 +- snap/snapcraft.yaml | 2 +- 10 files changed, 59 insertions(+), 25 deletions(-) create mode 100644 change_logs/release_v0.50.13.md diff --git a/Makefile b/Makefile index 9154aba6..35cb6f91 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ NAME := k9s -VERSION ?= v0.50.12 +VERSION ?= v0.50.13 PACKAGE := github.com/derailed/$(NAME) OUTPUT_BIN ?= execs/${NAME} GO_FLAGS ?= diff --git a/change_logs/release_v0.50.13.md b/change_logs/release_v0.50.13.md new file mode 100644 index 00000000..5efebf75 --- /dev/null +++ b/change_logs/release_v0.50.13.md @@ -0,0 +1,32 @@ + + +# Release v0.50.13 + +## 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/zt-3360a389v-ElLHrb0Dp1kAXqYUItSAFA) + +## Maintenance Release! + +## Resolved Issues + +* [#3587](https://github.com/derailed/k9s/issues/3587) UI doesn't show any updates when restarting a Deployment +* [#3585](https://github.com/derailed/k9s/issues/3585) abbreviation sec for secret not working +* [#3584](https://github.com/derailed/k9s/issues/3584) Show managed fields doesn't show them +* [#3583](https://github.com/derailed/k9s/issues/3583) Cannot open shell to pods without node read access as of 0.50.12 +* [#3577](https://github.com/derailed/k9s/issues/3577) Log view is broken as of v0.50.10 +* [#3574](https://github.com/derailed/k9s/issues/3574) Aliases for pods with label filters not working + +--- + © 2025 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)# \ No newline at end of file diff --git a/internal/client/gvr.go b/internal/client/gvr.go index 9747494a..2e13f9e2 100644 --- a/internal/client/gvr.go +++ b/internal/client/gvr.go @@ -88,7 +88,7 @@ func (g *GVR) IsCommand() bool { } func (g *GVR) IsK8sRes() bool { - return g != nil && ((strings.Contains(g.raw, "/") && !strings.Contains(g.raw, " /")) || reservedGVRs.Has(g)) + return g != nil && ((!strings.Contains(g.raw, " ") && strings.Contains(g.raw, "/") && !strings.Contains(g.raw, " /")) || reservedGVRs.Has(g)) } // WithSubResource builds a new gvr with a sub resource. diff --git a/internal/config/alias.go b/internal/config/alias.go index d64d3ba8..60c2d3f1 100644 --- a/internal/config/alias.go +++ b/internal/config/alias.go @@ -159,11 +159,15 @@ func (a *Aliases) LoadFile(path string) error { } a.mx.Lock() - defer a.mx.Unlock() if err := yaml.Unmarshal(bb, a); err != nil { return err } + for k, v := range a.Alias { + a.Alias[k] = client.NewGVR(v.String()) + } + defer a.mx.Unlock() + return nil } diff --git a/internal/dao/helpers.go b/internal/dao/helpers.go index 1d376b39..dcee0f46 100644 --- a/internal/dao/helpers.go +++ b/internal/dao/helpers.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "log/slog" - "maps" "math" "github.com/derailed/k9s/internal/client" @@ -95,17 +94,12 @@ func ToYAML(o runtime.Object, showManaged bool) (string, error) { return "", fmt.Errorf("expecting unstructured object but got nil") } - mm := u.Object - var ( - buff bytes.Buffer - p printers.YAMLPrinter - ) + var p printers.ResourcePrinter = &printers.YAMLPrinter{} if !showManaged { - mm = maps.Clone(mm) - if meta, ok := mm["metadata"].(map[string]any); ok { - delete(meta, "managedFields") - } + p = &printers.OmitManagedFieldsPrinter{Delegate: p} } + + var buff bytes.Buffer if err := p.PrintObj(o, &buff); err != nil { slog.Error("PrintObj failed", slogs.Error, err) return "", err diff --git a/internal/dao/pod.go b/internal/dao/pod.go index 806cae3b..0b252ace 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -71,9 +71,9 @@ func (p *Pod) shouldStopRetrying(path string) bool { switch pod.Status.Phase { case v1.PodSucceeded, v1.PodFailed: return true + default: + return false } - - return false } // Get returns a resource instance if found, else an error. diff --git a/internal/render/dp.go b/internal/render/dp.go index ed6cdba0..f29dcdf9 100644 --- a/internal/render/dp.go +++ b/internal/render/dp.go @@ -100,7 +100,7 @@ func (d Deployment) defaultRow(raw *unstructured.Unstructured, r *model1.Row) er strconv.Itoa(int(dp.Status.UpdatedReplicas)), strconv.Itoa(int(dp.Status.AvailableReplicas)), mapToStr(dp.Labels), - AsStatus(d.diagnose(desired, dp.Status.AvailableReplicas)), + AsStatus(d.diagnose(dp.Status.Replicas, dp.Status.AvailableReplicas)), ToAge(dp.GetCreationTimestamp()), } diff --git a/internal/render/sts.go b/internal/render/sts.go index 4293ada2..c4fbf7ac 100644 --- a/internal/render/sts.go +++ b/internal/render/sts.go @@ -66,30 +66,34 @@ func (s StatefulSet) defaultRow(raw *unstructured.Unstructured, r *model1.Row) e return err } + var desired int32 + if sts.Spec.Replicas != nil { + desired = *sts.Spec.Replicas + } r.ID = client.MetaFQN(&sts.ObjectMeta) r.Fields = model1.Fields{ sts.Namespace, sts.Name, computeVulScore(sts.Namespace, sts.Labels, &sts.Spec.Template.Spec), - strconv.Itoa(int(sts.Status.ReadyReplicas)) + "/" + strconv.Itoa(int(sts.Status.Replicas)), + strconv.Itoa(int(sts.Status.ReadyReplicas)) + "/" + strconv.Itoa(int(desired)), asSelector(sts.Spec.Selector), na(sts.Spec.ServiceName), podContainerNames(&sts.Spec.Template.Spec, true), podImageNames(&sts.Spec.Template.Spec, true), mapToStr(sts.Labels), - AsStatus(s.diagnose(sts.Spec.Replicas, sts.Status.Replicas, sts.Status.ReadyReplicas)), + AsStatus(s.diagnose(desired, sts.Status.Replicas, sts.Status.ReadyReplicas)), ToAge(sts.GetCreationTimestamp()), } return nil } -func (StatefulSet) diagnose(w *int32, d, r int32) error { - if d != r { - return fmt.Errorf("desired %d replicas got %d available", d, r) +func (StatefulSet) diagnose(d, c, r int32) error { + if c != r { + return fmt.Errorf("desired %d replicas got %d available", c, r) } - if w != nil && *w != r { - return fmt.Errorf("want %d replicas got %d available", *w, r) + if d != r { + return fmt.Errorf("want %d replicas got %d available", d, r) } return nil diff --git a/internal/view/exec.go b/internal/view/exec.go index 38eb60d0..236d94db 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -348,7 +348,7 @@ func sshIn(a *App, fqn, co string) error { cfg := a.Config.K9s.ShellPod platform, err := getPodOS(a.factory, fqn) if err != nil { - return fmt.Errorf("os detect failed: %w", err) + slog.Warn("os detect failed", slogs.Error, err) } args := buildShellArgs("exec", fqn, co, a.Conn().Config().Flags()) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 6154f8b1..2c091639 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: k9s base: core22 -version: 'v0.50.12' +version: 'v0.50.13' 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.