Skip to content

Commit

Permalink
K9s/release v0.32.4 (#2637)
Browse files Browse the repository at this point in the history
* [Bug] fix #2605

* [Bug] fix #2604

* [Bug] fix #2592

* [Bug] fix #2608

* [Bug] Fix #2612

* Rel v0.32.4
  • Loading branch information
derailed committed Mar 20, 2024
1 parent c31a48f commit d3027c8
Show file tree
Hide file tree
Showing 26 changed files with 214 additions and 142 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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.32.3
VERSION ?= v0.32.4
IMG_NAME := derailed/k9s
IMAGE := ${IMG_NAME}:${VERSION}

Expand Down
65 changes: 65 additions & 0 deletions change_logs/release_v0.32.4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s.png" align="center" width="800" height="auto"/>

# Release v0.32.4

## 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!

---

## ♫ Sounds Behind The Release ♭

Thinking of all you at KubeCon Paris!!
May I suggest a nice glass of `cold Merlote` or other fine grape juices from my country?

* [Le Gorille - George Brassens](https://www.youtube.com/watch?v=KVfwvk_yVyA)
* [Les Funerailles D'antan (Love this guy!) - George Brassens](https://www.youtube.com/watch?v=bwb5k4k2EMc)
* [Poinconneur Des Lilas - Serge Gainsbourg](https://www.youtube.com/watch?v=eWkWCFzkOvU)
* [Mon Legionaire (Yup! same guy??) - Serge Gainsbourg](https://www.youtube.com/watch?v=gl8gopryqWI)
* [Les Cornichons - Nino Ferrer](https://www.youtube.com/watch?v=N7JSW4NhM8I)
* [Paris s'eveille - Jacques Dutronc](https://www.youtube.com/watch?v=3WcCg6rm3uM)

---

## Videos Are In The Can!

Please dial [K9s Channel](https://www.youtube.com/channel/UC897uwPygni4QIjkPCpgjmw) for up coming content...

* [K9s v0.31.0 Configs+Sneak peek](https://youtu.be/X3444KfjguE)
* [K9s v0.30.0 Sneak peek](https://youtu.be/mVBc1XneRJ4)
* [Vulnerability Scans](https://youtu.be/ULkl0MsaidU)

---

## Resolved Issues

* [#2608](https://github.com/derailed/k9s/issues/2608) Make the sanitize feature easier to use
* [#2605](https://github.com/derailed/k9s/issues/2605) Built-in shortcuts being overridden by plugins result in excessive logging
* [#2604](https://github.com/derailed/k9s/issues/2604) Ability to mark a plugin as Dangerous/destructive
* [#2592](https://github.com/derailed/k9s/issues/2592) "list access denied" when switching contexts within k9s since 0.32.0

---

## 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!!

* [#2621](https://github.com/derailed/k9s/pull/2621) Fix snap build

---

<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2024 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
6 changes: 3 additions & 3 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,10 @@ func (a *APIClient) ServerVersion() (*version.Info, error) {
return info, nil
}

func (a *APIClient) IsValidNamespace(n string) bool {
ok, err := a.isValidNamespace(n)
func (a *APIClient) IsValidNamespace(ns string) bool {
ok, err := a.isValidNamespace(ns)
if err != nil {
log.Warn().Err(err).Msgf("namespace validation failed for: %q", n)
log.Warn().Err(err).Msgf("namespace validation failed for: %q", ns)
}

return ok
Expand Down
4 changes: 4 additions & 0 deletions internal/config/data/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package data

import (
"os"
"sync"

"github.com/derailed/k9s/internal/client"
Expand Down Expand Up @@ -70,6 +71,9 @@ func (c *Context) Validate(conn client.Connection, ks KubeSettings) {
c.mx.Lock()
defer c.mx.Unlock()

if a := os.Getenv(envPFAddress); a != "" {
c.PortForwardAddress = a
}
if c.PortForwardAddress == "" {
c.PortForwardAddress = defaultPFAddress()
}
Expand Down
1 change: 1 addition & 0 deletions internal/config/data/ns.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func NewActiveNamespace(n string) *Namespace {
if n == client.BlankNamespace {
n = client.DefaultNamespace
}

return &Namespace{
Active: n,
Favorites: []string{client.DefaultNamespace},
Expand Down
1 change: 1 addition & 0 deletions internal/config/json/schemas/plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"override": { "type": "boolean" },
"description": { "type": "string" },
"confirm": { "type": "boolean" },
"dangerous": { "type": "boolean" },
"scopes": {
"type": "array",
"items": { "type": "string" }
Expand Down
1 change: 1 addition & 0 deletions internal/config/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Plugin struct {
Command string `yaml:"command"`
Confirm bool `yaml:"confirm"`
Background bool `yaml:"background"`
Dangerous bool `yaml:"dangerous"`
}

func (p Plugin) String() string {
Expand Down
18 changes: 9 additions & 9 deletions internal/dao/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,19 +207,19 @@ func (p *Pod) TailLogs(ctx context.Context, opts *LogOptions) ([]LogChan, error)
return append(outs, tailLogs(ctx, p, opts)), nil
}
for _, co := range po.Spec.InitContainers {
o := opts.Clone()
o.Container = co.Name
outs = append(outs, tailLogs(ctx, p, o))
cfg := opts.Clone()
cfg.Container = co.Name
outs = append(outs, tailLogs(ctx, p, cfg))
}
for _, co := range po.Spec.Containers {
o := opts.Clone()
o.Container = co.Name
outs = append(outs, tailLogs(ctx, p, o))
cfg := opts.Clone()
cfg.Container = co.Name
outs = append(outs, tailLogs(ctx, p, cfg))
}
for _, co := range po.Spec.EphemeralContainers {
o := opts.Clone()
o.Container = co.Name
outs = append(outs, tailLogs(ctx, p, o))
cfg := opts.Clone()
cfg.Container = co.Name
outs = append(outs, tailLogs(ctx, p, cfg))
}

return outs, nil
Expand Down
10 changes: 7 additions & 3 deletions internal/render/sts.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,20 @@ func (s StatefulSet) Render(o interface{}, ns string, r *model1.Row) error {
podContainerNames(sts.Spec.Template.Spec, true),
podImageNames(sts.Spec.Template.Spec, true),
mapToStr(sts.Labels),
AsStatus(s.diagnose(sts.Status.Replicas, sts.Status.ReadyReplicas)),
AsStatus(s.diagnose(sts.Spec.Replicas, sts.Status.Replicas, sts.Status.ReadyReplicas)),
ToAge(sts.GetCreationTimestamp()),
}

return nil
}

func (StatefulSet) diagnose(d, r int32) error {
func (StatefulSet) diagnose(w *int32, d, r int32) error {
if d != r {
return fmt.Errorf("desiring %d replicas got %d available", d, r)
return fmt.Errorf("desired %d replicas got %d available", d, r)
}
if w != nil && *w != r {
return fmt.Errorf("want %d replicas got %d available", *w, r)
}

return nil
}
21 changes: 14 additions & 7 deletions internal/view/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func hotKeyActions(r Runner, aa *ui.KeyActions) error {
errs = errors.Join(errs, fmt.Errorf("duplicate hotkey found for %q in %q", hk.ShortCut, k))
continue
}
log.Info().Msgf("Action %q has been overridden by hotkey in %q", hk.ShortCut, k)
log.Debug().Msgf("Action %q has been overridden by hotkey in %q", hk.ShortCut, k)
}

command, err := r.EnvFn()().Substitute(hk.Command)
Expand Down Expand Up @@ -110,7 +110,6 @@ func gotoCmd(r Runner, cmd, path string, clearStack bool) ui.ActionHandler {
}

func pluginActions(r Runner, aa *ui.KeyActions) error {
pp := config.NewPlugins()
aa.Range(func(k tcell.Key, a ui.KeyAction) {
if a.Opts.Plugin {
aa.Delete(k)
Expand All @@ -121,12 +120,16 @@ func pluginActions(r Runner, aa *ui.KeyActions) error {
if err != nil {
return err
}
pp := config.NewPlugins()
if err := pp.Load(path); err != nil {
return err
}

var errs error
aliases := r.Aliases()
var (
errs error
aliases = r.Aliases()
ro = r.App().Config.K9s.IsReadOnly()
)
for k, plugin := range pp.Plugins {
if !inScope(plugin.Scopes, aliases) {
continue
Expand All @@ -141,15 +144,19 @@ func pluginActions(r Runner, aa *ui.KeyActions) error {
errs = errors.Join(errs, fmt.Errorf("duplicate plugin key found for %q in %q", plugin.ShortCut, k))
continue
}
log.Info().Msgf("Action %q has been overridden by plugin in %q", plugin.ShortCut, k)
log.Debug().Msgf("Action %q has been overridden by plugin in %q", plugin.ShortCut, k)
}

if plugin.Dangerous && ro {
continue
}
aa.Add(key, ui.NewKeyActionWithOpts(
plugin.Description,
pluginAction(r, plugin),
ui.ActionOpts{
Visible: true,
Plugin: true,
Visible: true,
Plugin: true,
Dangerous: plugin.Dangerous,
},
))
}
Expand Down
21 changes: 3 additions & 18 deletions internal/view/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@ func (a *App) Init(version string, rate int) error {
ns := a.Config.ActiveNamespace()

a.factory = watch.NewFactory(a.Conn())
ok, err := a.isValidNS(ns)
if !ok && err == nil {
return fmt.Errorf("app-init - invalid namespace: %q", ns)
}
a.initFactory(ns)

a.clusterModel = model.NewClusterInfo(a.factory, a.version, a.Config.K9s)
Expand Down Expand Up @@ -438,18 +434,6 @@ func (a *App) switchNS(ns string) error {
return a.factory.SetActiveNS(ns)
}

func (a *App) isValidNS(ns string) (bool, error) {
if ns == client.BlankNamespace || ns == client.NamespaceAll {
return true, nil
}

if !a.Conn().IsValidNamespace(ns) {
return false, fmt.Errorf("invalid namespace: %q", ns)
}

return true, nil
}

func (a *App) switchContext(ci *cmd.Interpreter, force bool) error {
name, ok := ci.HasContext()
if !ok || a.Config.ActiveContextName() == name {
Expand Down Expand Up @@ -477,12 +461,13 @@ func (a *App) switchContext(ci *cmd.Interpreter, force bool) error {
}
ns := a.Config.ActiveNamespace()
if !a.Conn().IsValidNamespace(ns) {
a.Flash().Errf("Unable to validate namespace %q. Using %q namespace", ns, client.DefaultNamespace)
ns = client.DefaultNamespace
log.Warn().Msgf("Unable to validate namespace: %q. Using %q as active namespace", ns, ns)
if err := a.Config.SetActiveNamespace(ns); err != nil {
return err
}
}
a.Flash().Errf("Using %q namespace", ns)

if err := a.Config.Save(true); err != nil {
log.Error().Err(err).Msg("config save failed!")
} else {
Expand Down
1 change: 1 addition & 0 deletions internal/view/details.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ func (d *Details) StylesChanged(s *config.Styles) {
// Update updates the view content.
func (d *Details) Update(buff string) *Details {
d.model.SetText(buff)

return d
}

Expand Down
41 changes: 4 additions & 37 deletions internal/view/dp.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,49 +53,16 @@ func (d *Deploy) logOptions(prev bool) (*dao.LogOptions, error) {
if path == "" {
return nil, errors.New("you must provide a selection")
}

sts, err := d.dp(path)
dp, err := d.getInstance(path)
if err != nil {
return nil, err
}

cc := sts.Spec.Template.Spec.Containers
var (
co, dco string
allCos bool
)
if c, ok := dao.GetDefaultContainer(sts.Spec.Template.ObjectMeta, sts.Spec.Template.Spec); ok {
co, dco = c, c
} else if len(cc) == 1 {
co = cc[0].Name
} else {
dco, allCos = cc[0].Name, true
}

cfg := d.App().Config.K9s.Logger
opts := dao.LogOptions{
Path: path,
Container: co,
Lines: int64(cfg.TailCount),
SinceSeconds: cfg.SinceSeconds,
SingleContainer: len(cc) == 1,
AllContainers: allCos,
ShowTimestamp: cfg.ShowTime,
Previous: prev,
}
if co == "" {
opts.AllContainers = true
}
opts.DefaultContainer = dco

return &opts, nil
return podLogOptions(d.App(), path, prev, dp.ObjectMeta, dp.Spec.Template.Spec), nil
}

func (d *Deploy) showPods(app *App, model ui.Tabular, gvr client.GVR, fqn string) {
var ddp dao.Deployment
ddp.Init(d.App().factory, d.GVR())

dp, err := ddp.GetInstance(fqn)
dp, err := d.getInstance(fqn)
if err != nil {
app.Flash().Err(err)
return
Expand All @@ -104,7 +71,7 @@ func (d *Deploy) showPods(app *App, model ui.Tabular, gvr client.GVR, fqn string
showPodsFromSelector(app, fqn, dp.Spec.Selector)
}

func (d *Deploy) dp(fqn string) (*appsv1.Deployment, error) {
func (d *Deploy) getInstance(fqn string) (*appsv1.Deployment, error) {
var dp dao.Deployment
dp.Init(d.App().factory, d.GVR())

Expand Down
Loading

0 comments on commit d3027c8

Please sign in to comment.