Skip to content

Commit

Permalink
K9s/release v0.30.5 (#2397)
Browse files Browse the repository at this point in the history
* [Bug] Fix #2393

* [Maint] Cleaning up

* rel docs
  • Loading branch information
derailed authored Dec 28, 2023
1 parent f5f3278 commit 9e337a6
Show file tree
Hide file tree
Showing 20 changed files with 225 additions and 110 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.4
VERSION ?= v0.30.5
IMG_NAME := derailed/k9s
IMAGE := ${IMG_NAME}:${VERSION}

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

# Release v0.30.5

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

* [#2394](https://github.com/derailed/k9s/issues/2394) Allow setting custom log dir
* [#2393](https://github.com/derailed/k9s/issues/2393) When switching contexts k9s does not switching to cluster's pod/namespaces/other k8s kinds view
* [#2387](https://github.com/derailed/k9s/issues/2387) Invalid namespace xxx - with feelings!

---

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

* [#2396](https://github.com/derailed/k9s/pull/2396) feat: allow to customize logs dir through environment variable
* [#2395](https://github.com/derailed/k9s/pull/2395) fix: create user tmp directory before the app one

---

<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)
25 changes: 16 additions & 9 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ func run(cmd *cobra.Command, args []string) error {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
zerolog.SetGlobalLevel(parseLevel(*k9sFlags.LogLevel))

app := view.NewApp(loadConfiguration())
cfg, err := loadConfiguration()
if err != nil {
return err
}
app := view.NewApp(cfg)
if err := app.Init(version, *k9sFlags.RefreshRate); err != nil {
return err
}
Expand All @@ -105,7 +109,7 @@ func run(cmd *cobra.Command, args []string) error {
return nil
}

func loadConfiguration() *config.Config {
func loadConfiguration() (*config.Config, error) {
log.Info().Msg("🐶 K9s starting up...")

k8sCfg := client.NewConfig(k8sFlags)
Expand All @@ -116,26 +120,29 @@ func loadConfiguration() *config.Config {
k9sCfg.K9s.Override(k9sFlags)
if err := k9sCfg.Refine(k8sFlags, k9sFlags, k8sCfg); err != nil {
log.Error().Err(err).Msgf("refine failed")
return nil, err
}
conn, err := client.InitConnection(k8sCfg)
k9sCfg.SetConnection(conn)
if err != nil {
log.Error().Err(err).Msgf("failed to connect to context %q", k9sCfg.K9s.ActiveContextName())
return k9sCfg
return nil, err
}
// Try to access server version if that fail. Connectivity issue?
if !k9sCfg.GetConnection().CheckConnectivity() {
log.Panic().Msgf("Cannot connect to context %s", k9sCfg.K9s.ActiveContextName())
if !conn.CheckConnectivity() {
return nil, fmt.Errorf("cannot connect to context: %s", k9sCfg.K9s.ActiveContextName())
}
if !k9sCfg.GetConnection().ConnectionOK() {
panic("No connectivity")
if !conn.ConnectionOK() {
return nil, fmt.Errorf("k8s connection failed for context: %s", k9sCfg.K9s.ActiveContextName())
}
k9sCfg.SetConnection(conn)

log.Info().Msg("✅ Kubernetes connectivity")
if err := k9sCfg.Save(); err != nil {
log.Error().Err(err).Msg("Config save")
return nil, err
}

return k9sCfg
return k9sCfg, nil
}

func parseLevel(level string) zerolog.Level {
Expand Down
22 changes: 13 additions & 9 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ type Config struct {

// K9sHome returns k9s configs home directory.
func K9sHome() string {
if env := os.Getenv(K9sConfigDir); env != "" {
return env
if isEnvSet(K9sEnvConfigDir) {
return os.Getenv(K9sEnvConfigDir)
}

xdgK9sHome, err := xdg.ConfigFile(AppName)
Expand Down Expand Up @@ -84,7 +84,7 @@ func (c *Config) Refine(flags *genericclioptions.ConfigFlags, k9sFlags *Flags, c
}
log.Debug().Msgf("Active Context %q", c.K9s.ActiveContextName())

var ns = client.DefaultNamespace
var ns string
switch {
case k9sFlags != nil && IsBoolSet(k9sFlags.AllNamespaces):
ns = client.NamespaceAll
Expand All @@ -97,10 +97,12 @@ func (c *Config) Refine(flags *genericclioptions.ConfigFlags, k9sFlags *Flags, c
}
ns = nss
}
if ns == "" {
ns = client.DefaultNamespace
}
if err := c.SetActiveNamespace(ns); err != nil {
return err
}
flags.Namespace = &ns

return data.EnsureDirPath(c.K9s.GetScreenDumpDir(), data.DefaultDirMod)
}
Expand Down Expand Up @@ -139,10 +141,10 @@ func (c *Config) ActiveNamespace() string {
// ValidateFavorites ensure favorite ns are legit.
func (c *Config) ValidateFavorites() {
ct, err := c.K9s.ActiveContext()
if err == nil {
ct.Validate(c.conn, c.settings)
ct.Namespace.Validate(c.conn, c.settings)
if err != nil {
return
}
ct.Validate(c.conn, c.settings)
}

// FavNamespaces returns fav namespaces in the current context.
Expand Down Expand Up @@ -197,8 +199,10 @@ func (c *Config) GetConnection() client.Connection {

// SetConnection set an api server connection.
func (c *Config) SetConnection(conn client.Connection) {
c.conn, c.K9s.conn = conn, conn
c.Validate()
c.conn = conn
if conn != nil {
c.K9s.resetConnection(conn)
}
}

func (c *Config) ActiveContextName() string {
Expand Down
4 changes: 0 additions & 4 deletions internal/config/data/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,13 @@ func (c *Context) Validate(conn client.Connection, ks KubeSettings) {
if c.PortForwardAddress == "" {
c.PortForwardAddress = DefaultPFAddress
}

if cl, err := ks.CurrentClusterName(); err != nil {
c.ClusterName = cl
}

if c.Namespace == nil {
c.Namespace = NewNamespace()
}
if c.Namespace.Active == client.BlankNamespace {
c.Namespace.Active = client.DefaultNamespace
}
c.Namespace.Validate(conn, ks)

if c.View == nil {
Expand Down
15 changes: 5 additions & 10 deletions internal/config/data/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,28 @@ import (
"os"
"path/filepath"

"github.com/derailed/k9s/internal/client"
"github.com/rs/zerolog/log"
"gopkg.in/yaml.v2"
"k8s.io/client-go/tools/clientcmd/api"
)

// Dir tracks context configurations.
type Dir struct {
root string
conn client.Connection
ks KubeSettings
}

func NewDir(root string, conn client.Connection, ks KubeSettings) *Dir {
// NewDir returns a new instance.
func NewDir(root string) *Dir {
return &Dir{
root: root,
ks: ks,
conn: conn,
}
}

func (d Dir) Load(n string, ct *api.Context) (*Config, error) {
// Load loads context configuration.
func (d *Dir) Load(n string, ct *api.Context) (*Config, error) {
if ct == nil {
return nil, errors.New("api.Context must not be nil")
}

var (
path = filepath.Join(d.root, SanitizeContextSubpath(ct.Cluster, n), MainConfigFile)
cfg *Config
Expand All @@ -51,7 +48,6 @@ func (d Dir) Load(n string, ct *api.Context) (*Config, error) {

func (d *Dir) genConfig(path string, ct *api.Context) (*Config, error) {
cfg := NewConfig(ct)
cfg.Validate(d.conn, d.ks)
if err := cfg.Save(path); err != nil {
return nil, err
}
Expand All @@ -68,7 +64,6 @@ func (d *Dir) loadConfig(path string) (*Config, error) {
if err := yaml.Unmarshal(bb, &cfg); err != nil {
return nil, err
}
cfg.Validate(d.conn, d.ks)

return &cfg, nil
}
2 changes: 1 addition & 1 deletion internal/config/data/dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func TestDirLoad(t *testing.T) {
assert.NoError(t, mock.EnsureDir(u.dir))
}

d := data.NewDir(u.dir, mock.NewMockConnection(), ks)
d := data.NewDir(u.dir)
ct, err := ks.CurrentContext()
assert.NoError(t, err)
if err != nil {
Expand Down
16 changes: 9 additions & 7 deletions internal/config/data/ns.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,30 @@ func NewNamespace() *Namespace {
}

func NewActiveNamespace(n string) *Namespace {
if n == client.BlankNamespace {
n = client.DefaultNamespace
}
return &Namespace{
Active: n,
Favorites: []string{client.DefaultNamespace},
}
}

// Validate a namespace is setup correctly.
// Validate validates a namespace is setup correctly.
func (n *Namespace) Validate(c client.Connection, ks KubeSettings) {
if c == nil {
n = NewActiveNamespace(client.DefaultNamespace)
if n.Active == client.BlankNamespace || c == nil {
n.Active = client.DefaultNamespace
}
if c == nil {
log.Debug().Msgf("No connection found. Skipping ns validation")
return
}
if !n.isAllNamespaces() && !c.IsValidNamespace(n.Active) {
log.Error().Msgf("[Config] Validation error active namespace %q does not exists", n.Active)
log.Error().Msgf("[Config] Validation failed active namespace %q does not exists. Resetting to default ns", n.Active)
n.Active = client.DefaultNamespace
}

for _, ns := range n.Favorites {
if ns != client.NamespaceAll && !c.IsValidNamespace(ns) {
log.Debug().Msgf("[Config] Invalid favorite found '%s' - %t", ns, n.isAllNamespaces())
log.Debug().Msgf("[Namespace] Invalid favorite found '%s' - %t", ns, n.isAllNamespaces())
n.rmFavNS(ns)
}
}
Expand Down
45 changes: 17 additions & 28 deletions internal/config/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package config
import (
_ "embed"
"os"
"os/user"
"path/filepath"

"github.com/derailed/k9s/internal/config/data"
Expand All @@ -16,11 +15,11 @@ import (
)

const (
// K9sConfigDir represents k9s configuration dir env var.
K9sConfigDir = "K9S_CONFIG_DIR"
// K9sEnvConfigDir represents k9s configuration dir env var.
K9sEnvConfigDir = "K9S_CONFIG_DIR"

// K9sLogsDir represents k9s logs dir env var.
K9sLogsDir = "K9S_LOGS_DIR"
// K9sEnvLogsDir represents k9s logs dir env var.
K9sEnvLogsDir = "K9S_LOGS_DIR"

// AppName tracks k9s app name.
AppName = "k9s"
Expand Down Expand Up @@ -84,14 +83,21 @@ var (
// InitLogsLoc initializes K9s logs location.
func InitLogLoc() error {
var appLogDir string
if envDir := os.Getenv(K9sLogsDir); envDir != "" {
appLogDir = envDir
} else {
tmpDir, err := userTmpDir()
switch {
case isEnvSet(K9sEnvLogsDir):
appLogDir = os.Getenv(K9sEnvLogsDir)
case isEnvSet(K9sEnvConfigDir):
tmpDir, err := UserTmpDir()
if err != nil {
return err
}
appLogDir = tmpDir
default:
var err error
appLogDir, err = xdg.StateFile(AppName)
if err != nil {
return err
}
}
if err := data.EnsureFullPath(appLogDir, data.DefaultDirMod); err != nil {
return err
Expand All @@ -103,15 +109,15 @@ func InitLogLoc() error {

// InitLocs initializes k9s artifacts locations.
func InitLocs() error {
if hasK9sConfigEnv() {
if isEnvSet(K9sEnvConfigDir) {
return initK9sEnvLocs()
}

return initXDGLocs()
}

func initK9sEnvLocs() error {
AppConfigDir = os.Getenv(K9sConfigDir)
AppConfigDir = os.Getenv(K9sEnvConfigDir)
if err := data.EnsureFullPath(AppConfigDir, data.DefaultDirMod); err != nil {
return err
}
Expand Down Expand Up @@ -269,20 +275,3 @@ func EnsureHotkeysCfgFile() (string, error) {
func SkinFileFromName(n string) string {
return filepath.Join(AppSkinsDir, n+".yaml")
}

// Helpers...

func hasK9sConfigEnv() bool {
return os.Getenv(K9sConfigDir) != ""
}

func userTmpDir() (string, error) {
u, err := user.Current()
if err != nil {
return "", err
}

dir := filepath.Join(os.TempDir(), u.Username, AppName)

return dir, nil
}
Loading

0 comments on commit 9e337a6

Please sign in to comment.