parent
1c19ef6ad6
commit
d0f874e01a
2
Makefile
2
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}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s.png" align="center" width="800" height="auto"/>
|
||||
|
||||
# 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
|
||||
|
||||
<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)
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
if n == nil {
|
||||
n = NewActiveNamespace(ns)
|
||||
} else {
|
||||
n.Active = ns
|
||||
}
|
||||
if ns != "" && !n.LockFavorites {
|
||||
n.addFavNS(ns)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ const (
|
|||
bannerFmt = "<<K9s-Shell>> 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue