Skip to content

Commit

Permalink
K9s/release v0.30.3 (#2381)
Browse files Browse the repository at this point in the history
* fix #2377

* fix #2379

* cleaning up

* Release docs
  • Loading branch information
derailed committed Dec 25, 2023
1 parent 463be69 commit 26d1585
Show file tree
Hide file tree
Showing 28 changed files with 346 additions and 218 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.30.2
VERSION ?= v0.30.3
IMG_NAME := derailed/k9s
IMAGE := ${IMG_NAME}:${VERSION}

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

# Release v0.30.3

## 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 twelfth day of Christmas my true love gave to me... More Bugs!!` 馃幍

Thank you all for pitching in and help 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

* [#2379](https://github.com/derailed/k9s/issues/2379) Filtering with equal sign (=) does not work in 0.30.X
* [#2378](https://github.com/derailed/k9s/issues/2378) Logs directory not created in the k9s config/home dir 0.30.1
* [#2377](https://github.com/derailed/k9s/issues/2377) Opening AWS EKS contexts create two directories per cluster 0.30.1

---

<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)
11 changes: 8 additions & 3 deletions internal/config/data/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,14 @@ func (d Dir) Load(n string, ct *api.Context) (*Config, error) {
}

var (
path = filepath.Join(d.root, ct.Cluster, n, MainConfigFile)
cfg *Config
err error
path = filepath.Join(
d.root,
SanitizeFileName(ct.Cluster),
SanitizeFileName(n),
MainConfigFile,
)
cfg *Config
err error
)
if f, e := os.Stat(path); os.IsNotExist(e) || f.Size() == 0 {
log.Debug().Msgf("Context config not found! Generating... %q", path)
Expand Down
6 changes: 6 additions & 0 deletions internal/config/data/dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ func TestDirLoad(t *testing.T) {
flags: makeFlags("cl-test", "ct-test-1"),
cfg: mustLoadConfig("testdata/configs/def_ct.yaml"),
},

"non-sanitized-path": {
dir: "/tmp/data/k9s",
flags: makeFlags("arn:aws:eks:eu-central-1:xxx:cluster/fred-blee", "fred-blee"),
cfg: mustLoadConfig("testdata/configs/aws_ct.yaml"),
},
}

for k := range uu {
Expand Down
13 changes: 13 additions & 0 deletions internal/config/data/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,21 @@ package data
import (
"os"
"path/filepath"
"regexp"
)

var invalidPathCharsRX = regexp.MustCompile(`[:/]+`)

// SanitizeContextSubpath ensure cluster/context produces a valid path.
func SanitizeContextSubpath(cluster, context string) string {
return filepath.Join(SanitizeFileName(cluster), SanitizeFileName(context))
}

// SanitizeFileName ensure file spec is valid.
func SanitizeFileName(name string) string {
return invalidPathCharsRX.ReplaceAllString(name, "-")
}

// InList check if string is in a collection of strings.
func InList(ll []string, n string) bool {
for _, l := range ll {
Expand Down
12 changes: 12 additions & 0 deletions internal/config/data/testdata/configs/aws_ct.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
k9s:
cluster: arn:aws:eks:eu-central-1:xxx:cluster/fred-blee
namespace:
active: default
lockFavorites: false
favorites:
- default
view:
active: po
featureGates:
nodeShell: false
portForwardAddress: localhost
40 changes: 11 additions & 29 deletions internal/config/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"os"
"os/user"
"path/filepath"
"regexp"

"github.com/derailed/k9s/internal/config/data"

Expand Down Expand Up @@ -81,19 +80,13 @@ var (

// InitLogsLoc initializes K9s logs location.
func InitLogLoc() error {
if hasK9sConfigEnv() {
tmpDir, err := userTmpDir()
if err != nil {
return err
}
AppLogFile = filepath.Join(tmpDir, K9sLogsFile)
return nil
tmpDir, err := userTmpDir()
if err != nil {
return err
}
AppLogFile = filepath.Join(tmpDir, K9sLogsFile)

var err error
AppLogFile, err = xdg.StateFile(filepath.Join(AppName, K9sLogsFile))

return err
return nil
}

// InitLocs initializes k9s artifacts locations.
Expand Down Expand Up @@ -182,31 +175,24 @@ func initXDGLocs() error {
return nil
}

var invalidPathCharsRX = regexp.MustCompile(`[:/]+`)

// SanitizeFileName ensure file spec is valid.
func SanitizeFileName(name string) string {
return invalidPathCharsRX.ReplaceAllString(name, "-")
}

// AppContextDir generates a valid context config dir.
func AppContextDir(cluster, context string) string {
return filepath.Join(AppContextsDir, sanContextSubpath(cluster, context))
return filepath.Join(AppContextsDir, data.SanitizeContextSubpath(cluster, context))
}

// AppContextAliasesFile generates a valid context specific aliases file path.
func AppContextAliasesFile(cluster, context string) string {
return filepath.Join(AppContextsDir, sanContextSubpath(cluster, context), "aliases.yaml")
return filepath.Join(AppContextsDir, data.SanitizeContextSubpath(cluster, context), "aliases.yaml")
}

// AppContextPluginsFile generates a valid context specific plugins file path.
func AppContextPluginsFile(cluster, context string) string {
return filepath.Join(AppContextsDir, sanContextSubpath(cluster, context), "plugins.yaml")
return filepath.Join(AppContextsDir, data.SanitizeContextSubpath(cluster, context), "plugins.yaml")
}

// AppContextHotkeysFile generates a valid context specific hotkeys file path.
func AppContextHotkeysFile(cluster, context string) string {
return filepath.Join(AppContextsDir, sanContextSubpath(cluster, context), "hotkeys.yaml")
return filepath.Join(AppContextsDir, data.SanitizeContextSubpath(cluster, context), "hotkeys.yaml")
}

// AppContextConfig generates a valid context config file path.
Expand All @@ -216,14 +202,14 @@ func AppContextConfig(cluster, context string) string {

// DumpsDir generates a valid context dump directory.
func DumpsDir(cluster, context string) (string, error) {
dir := filepath.Join(AppDumpsDir, sanContextSubpath(cluster, context))
dir := filepath.Join(AppDumpsDir, data.SanitizeContextSubpath(cluster, context))

return dir, data.EnsureDirPath(dir, data.DefaultDirMod)
}

// EnsureBenchmarksDir generates a valid benchmark results directory.
func EnsureBenchmarksDir(cluster, context string) (string, error) {
dir := filepath.Join(AppBenchmarksDir, sanContextSubpath(cluster, context))
dir := filepath.Join(AppBenchmarksDir, data.SanitizeContextSubpath(cluster, context))

return dir, data.EnsureDirPath(dir, data.DefaultDirMod)
}
Expand Down Expand Up @@ -274,10 +260,6 @@ func SkinFileFromName(n string) string {

// Helpers...

func sanContextSubpath(cluster, context string) string {
return filepath.Join(SanitizeFileName(cluster), SanitizeFileName(context))
}

func hasK9sConfigEnv() bool {
return os.Getenv(K9sConfigDir) != ""
}
Expand Down
5 changes: 0 additions & 5 deletions internal/config/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ import (
v1 "k8s.io/api/core/v1"
)

// SanitizeFilename sanitizes the dump filename.
func SanitizeFilename(name string) string {
return invalidPathCharsRX.ReplaceAllString(name, "-")
}

// InNSList check if ns is in an ns collection.
func InNSList(nn []interface{}, ns string) bool {
ss := make([]string, len(nn))
Expand Down
19 changes: 16 additions & 3 deletions internal/config/k9s.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func NewK9s(conn client.Connection, ks data.KubeSettings) *K9s {
}
}

// Save saves the k9s config to dis.
func (k *K9s) Save() error {
if k.activeConfig != nil {
path := filepath.Join(
Expand All @@ -70,6 +71,7 @@ func (k *K9s) Save() error {
return nil
}

// Refine merges k9s configs.
func (k *K9s) Refine(k1 *K9s) {
k.LiveViewAutoRefresh = k1.LiveViewAutoRefresh
k.ScreenDumpDir = k1.ScreenDumpDir
Expand All @@ -86,6 +88,7 @@ func (k *K9s) Refine(k1 *K9s) {
k.Thresholds = k1.Thresholds
}

// Override overrides k9s config from cli args.
func (k *K9s) Override(k9sFlags *Flags) {
if *k9sFlags.RefreshRate != DefaultRefreshRate {
k.OverrideRefreshRate(*k9sFlags.RefreshRate)
Expand All @@ -105,6 +108,7 @@ func (k *K9s) OverrideScreenDumpDir(dir string) {
k.manualScreenDumpDir = &dir
}

// GetScreenDumpDir fetch screen dumps dir.
func (k *K9s) GetScreenDumpDir() string {
screenDumpDir := k.ScreenDumpDir
if k.manualScreenDumpDir != nil && *k.manualScreenDumpDir != "" {
Expand All @@ -117,21 +121,29 @@ func (k *K9s) GetScreenDumpDir() string {
return screenDumpDir
}

// Reset resets configuration and context.
func (k *K9s) Reset() {
k.activeConfig, k.activeContextName = nil, ""
}

// ActiveScreenDumpsDir fetch context specific screen dumps dir.
func (k *K9s) ActiveScreenDumpsDir() string {
return filepath.Join(k.GetScreenDumpDir(), k.ActiveContextDir())
}

// ActiveContextDir fetch current cluster/context path.
func (k *K9s) ActiveContextDir() string {
if k.activeConfig == nil {
return "na"
}

return filepath.Join(
SanitizeFileName(k.activeConfig.Context.ClusterName),
SanitizeFileName(k.ActiveContextName()),
return data.SanitizeContextSubpath(
k.activeConfig.Context.ClusterName,
k.ActiveContextName(),
)
}

// ActiveContextNamespace fetch the context active ns.
func (k *K9s) ActiveContextNamespace() (string, error) {
if k.activeConfig != nil {
return k.activeConfig.Context.Namespace.Active, nil
Expand All @@ -140,6 +152,7 @@ func (k *K9s) ActiveContextNamespace() (string, error) {
return "", errors.New("context config is not set")
}

// ActiveContextName returns the active context name.
func (k *K9s) ActiveContextName() string {
return k.activeContextName
}
Expand Down
4 changes: 4 additions & 0 deletions internal/config/mock/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ func NewMockKubeSettings(f *genericclioptions.ConfigFlags) mockKubeSettings {
Cluster: *f.ClusterName,
Namespace: client.DefaultNamespace,
},
"fred-blee": {
Cluster: "arn:aws:eks:eu-central-1:xxx:cluster/fred-blee",
Namespace: client.DefaultNamespace,
},
},
}
}
Expand Down
28 changes: 15 additions & 13 deletions internal/render/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ func (p Pod) Render(o interface{}, ns string, row *Row) error {
cs := po.Status.ContainerStatuses
cr, _, rc := p.Statuses(cs)

c, r := p.gatherPodMX(&po, pwm.MX)
var ccmx []mv1beta1.ContainerMetrics
if pwm.MX != nil {
ccmx = pwm.MX.Containers
}
c, r := gatherCoMX(po.Spec.Containers, ccmx)
phase := p.Phase(&po)
row.ID = client.MetaFQN(po.ObjectMeta)
row.Fields = Fields{
Expand Down Expand Up @@ -232,22 +236,20 @@ func (p *PodWithMetrics) DeepCopyObject() runtime.Object {
return p
}

func (*Pod) gatherPodMX(pod *v1.Pod, mx *mv1beta1.PodMetrics) (c, r metric) {
rcpu, rmem := podRequests(pod.Spec.Containers)
func gatherCoMX(cc []v1.Container, ccmx []mv1beta1.ContainerMetrics) (c, r metric) {
rcpu, rmem := cosRequests(cc)
r.cpu, r.mem = rcpu.MilliValue(), rmem.Value()

lcpu, lmem := podLimits(pod.Spec.Containers)
lcpu, lmem := cosLimits(cc)
r.lcpu, r.lmem = lcpu.MilliValue(), lmem.Value()

if mx != nil {
ccpu, cmem := currentRes(mx)
c.cpu, c.mem = ccpu.MilliValue(), cmem.Value()
}
ccpu, cmem := currentRes(ccmx)
c.cpu, c.mem = ccpu.MilliValue(), cmem.Value()

return
}

func podLimits(cc []v1.Container) (resource.Quantity, resource.Quantity) {
func cosLimits(cc []v1.Container) (resource.Quantity, resource.Quantity) {
cpu, mem := new(resource.Quantity), new(resource.Quantity)
for _, c := range cc {
limits := c.Resources.Limits
Expand All @@ -264,7 +266,7 @@ func podLimits(cc []v1.Container) (resource.Quantity, resource.Quantity) {
return *cpu, *mem
}

func podRequests(cc []v1.Container) (resource.Quantity, resource.Quantity) {
func cosRequests(cc []v1.Container) (resource.Quantity, resource.Quantity) {
cpu, mem := new(resource.Quantity), new(resource.Quantity)
for _, c := range cc {
co := c
Expand All @@ -280,12 +282,12 @@ func podRequests(cc []v1.Container) (resource.Quantity, resource.Quantity) {
return *cpu, *mem
}

func currentRes(mx *mv1beta1.PodMetrics) (resource.Quantity, resource.Quantity) {
func currentRes(ccmx []mv1beta1.ContainerMetrics) (resource.Quantity, resource.Quantity) {
cpu, mem := new(resource.Quantity), new(resource.Quantity)
if mx == nil {
if ccmx == nil {
return *cpu, *mem
}
for _, co := range mx.Containers {
for _, co := range ccmx {
c, m := co.Usage.Cpu(), co.Usage.Memory()
cpu.Add(*c)
mem.Add(*m)
Expand Down

0 comments on commit 26d1585

Please sign in to comment.