Skip to content

Commit

Permalink
K9s/release v0.31.6 (#2487)
Browse files Browse the repository at this point in the history
* [Bug] Fix #2476

* rel v0.31.6
  • Loading branch information
derailed authored Jan 18, 2024
1 parent 5445ff4 commit a543f47
Show file tree
Hide file tree
Showing 36 changed files with 442 additions and 292 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.31.5
VERSION ?= v0.31.6
IMG_NAME := derailed/k9s
IMAGE := ${IMG_NAME}:${VERSION}

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

# Release v0.31.6

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

😱 More aftermath... 😱

Thank you all for pitching in and helping flesh out issues!!

Please make sure to add gory details to issues ie relevant configs, debug logs, etc...

Comments like: `same here!` or `me to!` doesn't really cut it for us to zero in ;(
Everyone has slightly different settings/platforms so every little bits of info helps with the resolves even if seemingly irrelevant.

---

## NOTE

In this drop, we've made k9s a bit more resilient (hopefully!) to configuration issues and in most cases k9s will come up but may exhibit `limp mode` behaviors.
Please double check your k9s logs if things don't work as expected and file an issue with the `gory` details!

☢️ This drop may cause `some disturbance in the farce!` ☢️

Please proceed with caution with this one as we did our best to attempt to address potential context config file corruption by eliminating race conditions.
It's late and I am operating on minimal sleep so I may have hosed some behaviors 🫣
If you experience k9s locking up or misbehaving, as per the above👆 you know what to do now and as customary
we will do our best to address them quickly to get you back up and running!

Thank you for your support, kindness and patience!

---

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

* [#2476](https://github.com/derailed/k9s/issues/2476) Pod's are not displayed for the selected namespace. Hopefully!
* [#2471](https://github.com/derailed/k9s/issues/2471) Shell autocomplete functions do not work correctly

---

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

* [#2480](https://github.com/derailed/k9s/pull/2480) Adding system arch to nodes view
* [#2477](https://github.com/derailed/k9s/pull/2477) Shell autocomplete for k8s flags

---

<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)
76 changes: 42 additions & 34 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ var (
out = colorable.NewColorableStdout()
)

type FlagError struct{ err error }
type flagError struct{ err error }

func (e *FlagError) Error() string { return e.err.Error() }
func (e flagError) Error() string { return e.err.Error() }

func init() {
if err := config.InitLogLoc(); err != nil {
fmt.Printf("Fail to init k9s logs location %s\n", err)
}

rootCmd.SetFlagErrorFunc(func(command *cobra.Command, err error) error {
return &FlagError{err: err}
return flagError{err: err}
})

rootCmd.AddCommand(versionCmd(), infoCmd())
Expand All @@ -68,8 +68,7 @@ func init() {
// Execute root command.
func Execute() {
if err := rootCmd.Execute(); err != nil {
var flagError *FlagError
if !errors.As(err, &flagError) {
if !errors.As(err, &flagError{}) {
panic(err)
}
}
Expand Down Expand Up @@ -128,35 +127,36 @@ func loadConfiguration() (*config.Config, error) {

k8sCfg := client.NewConfig(k8sFlags)
k9sCfg := config.NewConfig(k8sCfg)
var errs error
conn, err := client.InitConnection(k8sCfg)
k9sCfg.SetConnection(conn)
if err != nil {
return k9sCfg, err
errs = errors.Join(errs, err)
}

if err := k9sCfg.Load(config.AppConfigFile); err != nil {
return k9sCfg, err
errs = errors.Join(errs, err)
}
k9sCfg.K9s.Override(k9sFlags)
if err := k9sCfg.Refine(k8sFlags, k9sFlags, k8sCfg); err != nil {
log.Error().Err(err).Msgf("config refine failed")
return k9sCfg, err
errs = errors.Join(errs, err)
}
// Try to access server version if that fail. Connectivity issue?
if !conn.CheckConnectivity() {
return k9sCfg, fmt.Errorf("cannot connect to context: %s", k9sCfg.K9s.ActiveContextName())
errs = errors.Join(errs, fmt.Errorf("cannot connect to context: %s", k9sCfg.K9s.ActiveContextName()))
}
if !conn.ConnectionOK() {
return k9sCfg, fmt.Errorf("k8s connection failed for context: %s", k9sCfg.K9s.ActiveContextName())
errs = errors.Join(errs, fmt.Errorf("k8s connection failed for context: %s", k9sCfg.K9s.ActiveContextName()))
}

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

return k9sCfg, nil
return k9sCfg, errs
}

func parseLevel(level string) zerolog.Level {
Expand Down Expand Up @@ -351,50 +351,58 @@ func initCertFlags() {
)
}

type (
k8sPickerFn[T any] func(cfg *api.Config) map[string]T
completeFn func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective)
)

func initK8sFlagCompletion() {
_ = rootCmd.RegisterFlagCompletionFunc("context", k8sFlagCompletionFunc(func(cfg *api.Config) map[string]*api.Context {
conn := client.NewConfig(k8sFlags)
cfg, err := conn.RawConfig()
if err != nil {
log.Error().Err(err).Msgf("k8s config getter failed")
}

_ = rootCmd.RegisterFlagCompletionFunc("context", k8sFlagCompletion(&cfg, func(cfg *api.Config) map[string]*api.Context {
return cfg.Contexts
}))

_ = rootCmd.RegisterFlagCompletionFunc("cluster", k8sFlagCompletionFunc(func(cfg *api.Config) map[string]*api.Cluster {
_ = rootCmd.RegisterFlagCompletionFunc("cluster", k8sFlagCompletion(&cfg, func(cfg *api.Config) map[string]*api.Cluster {
return cfg.Clusters
}))

_ = rootCmd.RegisterFlagCompletionFunc("user", k8sFlagCompletionFunc(func(cfg *api.Config) map[string]*api.AuthInfo {
_ = rootCmd.RegisterFlagCompletionFunc("user", k8sFlagCompletion(&cfg, func(cfg *api.Config) map[string]*api.AuthInfo {
return cfg.AuthInfos
}))

_ = rootCmd.RegisterFlagCompletionFunc("namespace", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
conn, err := client.InitConnection(client.NewConfig(k8sFlags))
if err != nil {
return nil, cobra.ShellCompDirectiveError
_ = rootCmd.RegisterFlagCompletionFunc("namespace", func(cmd *cobra.Command, args []string, s string) ([]string, cobra.ShellCompDirective) {
if c, err := client.InitConnection(conn); err == nil {
if nss, err := c.ValidNamespaceNames(); err == nil {
return filterFlagCompletions(nss, s)
}
}

nss, err := conn.ValidNamespaceNames()
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

return filterFlagCompletions(nss, toComplete)
return nil, cobra.ShellCompDirectiveError
})
}

func k8sFlagCompletionFunc[T any](picker func(cfg *api.Config) map[string]T) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
func k8sFlagCompletion[T any](cfg *api.Config, picker k8sPickerFn[T]) completeFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
k8sCfg, err := client.NewConfig(k8sFlags).RawConfig()
if err != nil {
if cfg == nil {
return nil, cobra.ShellCompDirectiveError
}
return filterFlagCompletions(picker(&k8sCfg), toComplete)

return filterFlagCompletions(picker(cfg), toComplete)
}
}

func filterFlagCompletions[T any](m map[string]T, toComplete string) ([]string, cobra.ShellCompDirective) {
var completions []string
func filterFlagCompletions[T any](m map[string]T, s string) ([]string, cobra.ShellCompDirective) {
cc := make([]string, 0, len(m))
for name := range m {
if strings.HasPrefix(name, toComplete) {
completions = append(completions, name)
if strings.HasPrefix(name, s) {
cc = append(cc, name)
}
}
return completions, cobra.ShellCompDirectiveNoFileComp

return cc, cobra.ShellCompDirectiveNoFileComp
}
Loading

0 comments on commit a543f47

Please sign in to comment.