K9s/release v0.30.1 (#2369)

* [Bug] Fix #2368

* [Bug] Fix #2363

* [Bug] Fix #2364

* [Bug] Fix #2366

* [Bug] Fix #2367

* Release docs + rebase fixes
mine
Fernand Galiana 2023-12-24 11:29:22 -07:00 committed by GitHub
parent f8ad4aa8c7
commit f0d0e62b70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 235 additions and 128 deletions

View File

@ -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.0
VERSION ?= v0.30.1
IMG_NAME := derailed/k9s
IMAGE := ${IMG_NAME}:${VERSION}

View File

@ -0,0 +1,57 @@
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s-xmas.png" align="center" width="800" height="auto"/>
# Release v0.30.1
## 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! 🎄
🎵 `On The twentyfouth day of Christmas my true love gave to me... Bugs!!` 🎵
Got to love the aftermath... Thank you all for pitch'in in and help flesh out bugs!! The gift that keeps on... giving?
🎅 Merry Christmas to all and Best wishes for the new year!!🧑‍🎄
---
### 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
* [#2368](https://github.com/derailed/k9s/issues/2368) Pod CPU and MEM columns are empty in 0.30.0
* [#2367](https://github.com/derailed/k9s/issues/2367) k9s 0.30.0 issue loading plugins
* [#2366](https://github.com/derailed/k9s/issues/2366) List pods of deployment is now impossible
* [#2264](https://github.com/derailed/k9s/issues/2264) k9s 0.30.0 fields and values missed in action in the "namespace view"
* [#2263](https://github.com/derailed/k9s/issues/2263) Default 0.30.0 default skin on macOS is no good
---
## 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!!
* [#2360](https://github.com/derailed/k9s/pull/2360) adding cancelable launch prompts to NodeShell
---
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2023 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)

View File

@ -541,7 +541,6 @@ func (s *Styles) Load(path string) error {
if err != nil {
return err
}
if err := yaml.Unmarshal(f, s); err != nil {
return err
}

View File

@ -17,24 +17,24 @@ k9s:
bgColor: black
suggestColor: dodgerblue
border:
default: seagreen
command: aqua
info:
fgColor: orange
sectionColor: white
dialog:
fgColor: dodgerblue
default: seagreen
help:
fgColor: cadetblue
bgColor: black
buttonFgColor: black
buttonBgColor: dodgerblue
buttonFocusFgColor: white
buttonFocusBgColor: fuchsia
labelFgColor: fuchsia
fieldFgColor: dodgerblue
sectionColor: green
keyColor: dodgerblue
numKeyColor: fuchsia
frame:
title:
fgColor: aqua
bgColor: black
highlightColor: fuchsia
counterColor: papayawhip
filterColor: seagreen
border:
fgColor: dodgerblue
focusColor: aqua
focusColor: lightskyblue
menu:
fgColor: white
keyColor: dodgerblue
@ -46,52 +46,71 @@ k9s:
status:
newColor: lightskyblue
modifyColor: greenyellow
addColor: white
errorColor: orangered
addColor: dodgerblue
pendingColor: darkorange
errorColor: orangered
highlightColor: aqua
killColor: mediumpurple
completedColor: gray
title:
fgColor: aqua
highlightColor: fuchsia
counterColor: papayawhip
filterColor: steelblue
completedColor: lightslategray
info:
sectionColor: white
fgColor: orange
views:
# Charts skins...
charts:
bgColor: black
defaultDialColors:
- linegreen
- orangered
defaultChartColors:
- linegreen
- orangered
table:
fgColor: aqua
bgColor: black
cursorFgColor: white
cursorBgColor: black
markColor: darkgoldenrod
cursorFgColor: black
cursorBgColor: aqua
markColor: palegreen
header:
fgColor: lightGray
fgColor: white
bgColor: black
sorterColor: orange
sorterColor: aqua
xray:
fgColor: blue
fgColor: aqua
bgColor: black
cursorColor: aqua
graphicColor: darkgoldenrod
showIcons: false
cursorColor: dodgerblue
cursorTextColor: black
graphicColor: cadetblue
charts:
bgColor: black
dialBgColor: black
chartBgColor: black
defaultDialColors:
- palegreen
- orangered
defaultChartColors:
- palegreen
- orangered
resourceColors:
cpu:
- dodgerblue
- darkslateblue
mem:
- yellow
- goldenrod
yaml:
keyColor: steelblue
colonColor: white
valueColor: papayawhip
colonColor: white
picker:
mainColor: white
focusColor: aqua
shortcutColor: aqua
logs:
fgColor: white
fgColor: lightskyblue
bgColor: black
indicator:
fgColor: dodgerblue
bgColor: black
toggleOnColor: limegreen
toggleOffColor: steelblue
toggleOffColor: gray
dialog:
fgColor: cadetblue
bgColor: black
buttonFgColor: black
buttonBgColor: darkslateblue
buttonFocusFgColor: black
buttonFocusBgColor: dodgerblue
labelFgColor: white
fieldFgColor: white

View File

@ -38,7 +38,7 @@ func (c *Container) List(ctx context.Context, _ string) ([]runtime.Object, error
cmx client.ContainersMetrics
err error
)
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); withMx || !ok {
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); ok && withMx {
cmx, _ = client.DialMetrics(c.Client()).FetchContainersMetrics(ctx, fqn)
}

View File

@ -139,7 +139,7 @@ func (n *Node) Get(ctx context.Context, path string) (runtime.Object, error) {
}
var nmx *mv1beta1.NodeMetrics
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); withMx || !ok {
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); ok && withMx {
nmx, _ = client.DialMetrics(n.Client()).FetchNodeMetrics(ctx, path)
}

View File

@ -70,7 +70,7 @@ func (p *Pod) Get(ctx context.Context, path string) (runtime.Object, error) {
}
var pmx *mv1beta1.PodMetrics
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); withMx || !ok {
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); ok && withMx {
pmx, _ = client.DialMetrics(p.Client()).FetchPodMetrics(ctx, path)
}
@ -95,7 +95,7 @@ func (p *Pod) List(ctx context.Context, ns string) ([]runtime.Object, error) {
}
var pmx client.PodsMetricsMap
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); false && ok && withMx {
if withMx, ok := ctx.Value(internal.KeyWithMetrics).(bool); ok && withMx {
pmx, _ = client.DialMetrics(p.Client()).FetchPodsMetricsMap(ctx, ns)
}
sel, _ := ctx.Value(internal.KeyLabels).(string)

View File

@ -101,8 +101,8 @@ func (Pod) Header(ns string) Header {
HeaderColumn{Name: "%CPU/L", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%MEM/R", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "%MEM/L", Align: tview.AlignRight, MX: true},
HeaderColumn{Name: "IP", Wide: true},
HeaderColumn{Name: "NODE", Wide: true},
HeaderColumn{Name: "IP"},
HeaderColumn{Name: "NODE"},
HeaderColumn{Name: "NOMINATED NODE", Wide: true},
HeaderColumn{Name: "READINESS GATES", Wide: true},
HeaderColumn{Name: "QOS", Wide: true},

View File

@ -148,8 +148,7 @@ func (c *Configurator) RefreshStyles(context string) {
var skin string
if c.Config != nil {
skin = c.Config.K9s.UI.Skin
ct, err := c.Config.K9s.ActiveContext()
if err != nil {
if ct, err := c.Config.K9s.ActiveContext(); err != nil {
log.Warn().Msgf("No active context found. Using default skin")
} else if ct.Skin != "" {
skin = ct.Skin

View File

@ -1,3 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of K9s
package dialog
import (

View File

@ -1,14 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of K9s
package dialog
import (
"context"
"testing"
"time"
"github.com/derailed/k9s/internal/config"
"github.com/derailed/k9s/internal/ui"
"github.com/derailed/tcell/v2"
"github.com/derailed/tview"
"github.com/stretchr/testify/assert"
"testing"
"time"
)
func TestShowPrompt(t *testing.T) {

View File

@ -22,6 +22,8 @@ import (
"golang.org/x/text/language"
)
const maxTruncate = 50
type (
// ColorerFunc represents a row colorer.
ColorerFunc func(ns string, evt render.RowEvent) tcell.Color
@ -469,9 +471,9 @@ func (t *Table) styleTitle() string {
buff := t.cmdBuff.GetText()
if IsLabelSelector(buff) {
buff = TrimLabelSelector(buff)
buff = truncate(TrimLabelSelector(buff), maxTruncate)
} else if l := t.GetModel().GetLabelFilter(); l != "" {
buff = l
buff = truncate(l, maxTruncate)
}
if buff == "" {

View File

@ -104,6 +104,14 @@ func TrimLabelSelector(s string) string {
return s
}
func truncate(s string, max int) string {
if len(s) < max {
return s
}
return s[:max] + "..."
}
// SkinTitle decorates a title.
func SkinTitle(fmat string, style config.Frame) string {
bgColor := style.Title.BgColor

View File

@ -9,6 +9,29 @@ import (
"github.com/stretchr/testify/assert"
)
func TestTruncate(t *testing.T) {
uu := map[string]struct {
s, e string
}{
"empty": {},
"max": {
s: "/app.kubernetes.io/instance=prom,app.kubernetes.io/name=prometheus,app.kubernetes.io/component=server",
e: "/app.kubernetes.io/instance=prom,app.kubernetes.io...",
},
"less": {
s: "app=fred,env=blee",
e: "app=fred,env=blee",
},
}
for k := range uu {
u := uu[k]
t.Run(k, func(t *testing.T) {
assert.Equal(t, u.e, truncate(u.s, 50))
})
}
}
func TestIsLabelSelector(t *testing.T) {
uu := map[string]struct {
s string

View File

@ -38,7 +38,7 @@ func newArgs(p *Interpreter, aa []string) args {
args[filterKey] = a[1:]
case strings.Contains(a, labelFlag):
if ll := toLabels(a); len(ll) != 0 {
if ll := ToLabels(a); len(ll) != 0 {
args[labelKey] = a
}

View File

@ -11,7 +11,7 @@ import (
"github.com/rs/zerolog/log"
)
func toLabels(s string) map[string]string {
func ToLabels(s string) map[string]string {
ll := strings.Split(s, ",")
lbls := make(map[string]string, len(ll))
for _, l := range ll {

View File

@ -53,7 +53,7 @@ func Test_toLabels(t *testing.T) {
for k := range uu {
u := uu[k]
t.Run(k, func(t *testing.T) {
assert.Equal(t, u.ll, toLabels(u.s))
assert.Equal(t, u.ll, ToLabels(u.s))
})
}
}

View File

@ -196,5 +196,5 @@ func (c *Interpreter) LabelsArg() (map[string]string, bool) {
return nil, false
}
return toLabels(ll), true
return ToLabels(ll), true
}

View File

@ -18,6 +18,7 @@ import (
"github.com/derailed/k9s/internal/model"
"github.com/derailed/k9s/internal/render"
"github.com/derailed/k9s/internal/ui"
"github.com/derailed/k9s/internal/view/cmd"
"github.com/derailed/tcell/v2"
"github.com/derailed/tview"
"github.com/rs/zerolog/log"
@ -116,13 +117,9 @@ func toLabelsStr(labels map[string]string) string {
}
func showPods(app *App, path, labelSel, fieldSel string) {
// !!BOZO!! needed??
// if err := app.switchNS(client.BlankNamespace); err != nil {
// app.Flash().Err(err)
// return
// }
v := NewPod(client.NewGVR("v1/pods"))
v.SetContextFn(podCtx(app, path, labelSel, fieldSel))
v.SetContextFn(podCtx(app, path, fieldSel))
v.SetLabelFilter(cmd.ToLabels(labelSel))
ns, _ := client.Namespaced(path)
if err := app.Config.SetActiveNamespace(ns); err != nil {
@ -133,11 +130,9 @@ func showPods(app *App, path, labelSel, fieldSel string) {
}
}
func podCtx(app *App, path, labelSel, fieldSel string) ContextFunc {
func podCtx(app *App, path, fieldSel string) ContextFunc {
return func(ctx context.Context) context.Context {
ctx = context.WithValue(ctx, internal.KeyPath, path)
ctx = context.WithValue(ctx, internal.KeyLabels, labelSel)
return context.WithValue(ctx, internal.KeyFields, fieldSel)
}
}

View File

@ -9,7 +9,6 @@ import (
"github.com/derailed/k9s/internal/config"
"github.com/derailed/tview"
"github.com/rs/zerolog/log"
)
const spacer = " "
@ -155,7 +154,5 @@ func (l *LogIndicator) Refresh() {
l.indicator = append(l.indicator, fmt.Sprintf(toggleOffFmt, "Wrap", "")...)
}
log.Debug().Msgf("INDICATOR: %q", l.indicator)
_, _ = l.Write(l.indicator)
}

View File

@ -18,10 +18,10 @@ func TestLogIndicatorRefresh(t *testing.T) {
e string
}{
"all-containers": {
view.NewLogIndicator(config.NewConfig(nil), defaults, true), "[::b]AllContainers:[steelblue::d]Off[-::] [::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[steelblue::d]Off[-::] [::b]Timestamps:[steelblue::d]Off[-::] [::b]Wrap:[steelblue::d]Off[-::]\n",
view.NewLogIndicator(config.NewConfig(nil), defaults, true), "[::b]AllContainers:[gray::d]Off[-::] [::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[gray::d]Off[-::] [::b]Timestamps:[gray::d]Off[-::] [::b]Wrap:[gray::d]Off[-::]\n",
},
"plain": {
view.NewLogIndicator(config.NewConfig(nil), defaults, false), "[::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[steelblue::d]Off[-::] [::b]Timestamps:[steelblue::d]Off[-::] [::b]Wrap:[steelblue::d]Off[-::]\n",
view.NewLogIndicator(config.NewConfig(nil), defaults, false), "[::b]Autoscroll:[limegreen::b]On[-::] [::b]FullScreen:[gray::d]Off[-::] [::b]Timestamps:[gray::d]Off[-::] [::b]Wrap:[gray::d]Off[-::]\n",
},
}

View File

@ -14,6 +14,7 @@ import (
"github.com/derailed/k9s/internal/ui"
"github.com/derailed/k9s/internal/ui/dialog"
"github.com/derailed/tcell/v2"
"github.com/rs/zerolog/log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

View File

@ -1,5 +1,5 @@
# $HOME/.k9s/plugin.yml
plugin:
plugins:
kapp-inspect:
shortCut: Shift-Z
confirm: false

View File

@ -1,4 +1,4 @@
plugin:
plugins:
# List all the resources managed by a Composite Resource
kube-lineage:
shortCut: Ctrl-X

View File

@ -1,4 +1,4 @@
plugin:
plugins:
#--- Create debug container for selected pod in current namespace
# See https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#ephemeral-container
debug:

View File

@ -1,4 +1,4 @@
plugin:
plugins:
dive:
shortCut: d
confirm: false

View File

@ -2,7 +2,7 @@
# move selected line to chosen resource in K9s, then:
# Shift-T (with confirmation) to toggle helm releases or kustomizations suspend and resume
# Shift-R (no confirmation) to reconcile a git source or a helm release or a kustomization
plugin:
plugins:
toggle-helmrelease:
shortCut: Shift-T
confirm: true

View File

@ -1,4 +1,4 @@
plugin:
plugins:
#get all resources in a namespace using the krew get-all plugin
get-all-namespace:
shortCut: g

View File

@ -1,4 +1,4 @@
plugin:
plugins:
helm-default-values:
shortCut: Shift-V
confirm: false

View File

@ -1,5 +1,5 @@
# $HOME/.k9s/plugin.yml
plugin:
plugins:
# Issues a helm delete --purge for the resource associated with the selected pod
helm-purge:
shortCut: Ctrl-P

View File

@ -1,6 +1,6 @@
# View user-supplied values when the helm chart was created
plugin:
plugins:
helm-values:
shortCut: v
confirm: false

View File

@ -1,4 +1,4 @@
plugin:
plugins:
# Suspends/Resumes a cronjob
toggleCronjob:
shortCut: Ctrl-S

View File

@ -1,4 +1,4 @@
plugin:
plugins:
# Opens a shell to k3d container as root
k3d-root-shell:
shortCut: Shift-S

View File

@ -1,4 +1,4 @@
plugin:
plugins:
# See https://k9scli.io/topics/plugins/
raw-logs-follow:
shortCut: Ctrl-L

View File

@ -1,4 +1,4 @@
plugin:
plugins:
# Sends logs over to jq for processing. This leverages kubectl plugin kubectl-jq.
jqlogs:
shortCut: Ctrl-J

View File

@ -1,4 +1,4 @@
plugin:
plugins:
# Leverage stern (https://github.com/stern/stern) to output logs.
stern:
shortCut: Ctrl-L

View File

@ -1,4 +1,4 @@
plugin:
plugins:
# remove finalizers from a stuck namespace
rm-ns:
shortCut: n

View File

@ -2,7 +2,7 @@
# requires linux "watch" command
# change '-n' to adjust refresh time in seconds
plugin:
plugins:
watch-events:
shortCut: Shift-E
confirm: false

View File

@ -31,7 +31,7 @@ apps:
parts:
build:
plugin: go
plugins: go
source: https://github.com/derailed/k9s.git
source-tag: $SNAPCRAFT_PROJECT_VERSION
override-build: |