From 0bc2e1764b38d8056174459e1752d8ccf4d36c35 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 6 Aug 2021 01:04:39 +0200 Subject: [PATCH] Make k9s configuration compatible with XDG Base Directory Specification to not pollute user home directories. (#1025) * Make k9s configuration compatible with XDG Base Directory Specification to not pollute user home directories. * Update readme to include new configuration directory. * Replace spaces with tabs.. :) * Remove extra backslash in Windows configuration directory path. Co-authored-by: Fernand Galiana --- README.md | 36 ++++++++++++++------------ go.mod | 1 + go.sum | 2 ++ go_BACKUP_36796.mod | 53 ++++++++++++++++++++++++++++++++++++++ go_BASE_36796.mod | 48 ++++++++++++++++++++++++++++++++++ go_LOCAL_36796.mod | 47 +++++++++++++++++++++++++++++++++ go_REMOTE_36796.mod | 49 +++++++++++++++++++++++++++++++++++ internal/config/config.go | 9 ++++--- internal/config/helpers.go | 8 ------ 9 files changed, 226 insertions(+), 27 deletions(-) create mode 100644 go_BACKUP_36796.mod create mode 100644 go_BASE_36796.mod create mode 100644 go_LOCAL_36796.mod create mode 100644 go_REMOTE_36796.mod diff --git a/README.md b/README.md index 6ac1ee5863..8f9bd6bd58 100644 --- a/README.md +++ b/README.md @@ -206,7 +206,7 @@ k9s info # |____|__ \ /____//____ > # \/ \/ # -# Configuration: /Users/fernand/.k9s/config.yml +# Configuration: ~/Library/Preferences/k9s/config.yml # Logs: /var/folders/8c/hh6rqbgs5nx_c_8k9_17ghfh0000gn/T/k9s-fernand.log # Screen Dumps: /var/folders/8c/hh6rqbgs5nx_c_8k9_17ghfh0000gn/T/k9s-screens-fernand @@ -277,12 +277,16 @@ K9s uses aliases to navigate most K8s resources. ## K9s Configuration - K9s keeps its configurations in a .k9s directory in your home directory `$HOME/.k9s/config.yml`. + K9s keeps its configurations inside of a `k9s` directory and the location depends on your operating system. + + | Unix | macOS | Windows | + |-----------------|-----------------------------|-----------------------| + | `~/.config/k9s` | `~/Library/Preferences/k9s` | `%LOCALAPPDATA%\k9s` | > NOTE: This is still in flux and will change while in pre-release stage! ```yaml - # $HOME/.k9s/config.yml + # $HOME/.config/k9s/config.yml k9s: # Represents ui poll intervals. Default 2secs refreshRate: 2 @@ -359,7 +363,7 @@ K9s uses aliases to navigate most K8s resources. By enabling the nodeShell feature gate on a given cluster, K9s allows you to shell into your cluster nodes. Once enabled, you will have a new `s` for `shell` menu option while in node view. K9s will launch a pod on the selected node using a special k9s_shell pod. Furthermore, you can refine your shell pod by using a custom docker image preloaded with the shell tools you love. By default k9s uses a BusyBox image, but you can configure it as follows: ```yaml -# $HOME/.k9s/config.yml +# $HOME/.config/k9s/config.yml k9s: clusters: # Configures node shell on cluster blee @@ -380,10 +384,10 @@ k9s: ## Command Aliases -In K9s, you can define your very own command aliases (shortnames) to access your resources. In your `$HOME/.k9s` define a file called `alias.yml`. A K9s alias defines pairs of alias:gvr. A gvr (Group/Version/Resource) represents a fully qualified Kubernetes resource identifier. Here is an example of an alias file: +In K9s, you can define your very own command aliases (shortnames) to access your resources. In your `$HOME/.config/k9s` define a file called `alias.yml`. A K9s alias defines pairs of alias:gvr. A gvr (Group/Version/Resource) represents a fully qualified Kubernetes resource identifier. Here is an example of an alias file: ```yaml -# $HOME/.k9s/alias.yml +# $HOME/.config/k9s/alias.yml alias: pp: v1/pods crb: rbac.authorization.k8s.io/v1/clusterrolebindings @@ -397,11 +401,11 @@ Using this alias file, you can now type pp/crb to list pods or ClusterRoleBindin Entering the command mode and typing a resource name or alias, could be cumbersome for navigating thru often used resources. We're introducing hotkeys that allows a user to define their own hotkeys to activate their favorite resource views. In order to enable hotkeys please follow these steps: -1. Create a file named `$HOME/.k9s/hotkey.yml` +1. Create a file named `$HOME/.config/k9s/hotkey.yml` 2. Add the following to your `hotkey.yml`. You can use resource name/short name to specify a command ie same as typing it while in command mode. ```yaml - # $HOME/.k9s/hotkey.yml + # $HOME/.config/k9s/hotkey.yml hotKey: # Hitting Shift-0 navigates to your pod view shift-0: @@ -432,14 +436,14 @@ Entering the command mode and typing a resource name or alias, could be cumberso [SneakCast v0.17.0 on The Beach! - Yup! sound is sucking but what a setting!](https://youtu.be/7S33CNLAofk) -You can change which columns shows up for a given resource via custom views. To surface this feature, you will need to create a new configuration file, namely `$HOME/.k9s/views.yml`. This file leverages GVR (Group/Version/Resource) to configure the associated table view columns. If no GVR is found for a view the default rendering will take over (ie what we have now). Going wide will add all the remaining columns that are available on the given resource after your custom columns. To boot, you can edit your views config file and tune your resources views live! +You can change which columns shows up for a given resource via custom views. To surface this feature, you will need to create a new configuration file, namely `$HOME/.config/k9s/views.yml`. This file leverages GVR (Group/Version/Resource) to configure the associated table view columns. If no GVR is found for a view the default rendering will take over (ie what we have now). Going wide will add all the remaining columns that are available on the given resource after your custom columns. To boot, you can edit your views config file and tune your resources views live! > NOTE: This is experimental and will most likely change as we iron this out! Here is a sample views configuration that customize a pods and services views. ```yaml -# $HOME/.k9s/views.yml +# $HOME/.config/k9s/views.yml k9s: views: v1/pods: @@ -464,7 +468,7 @@ k9s: ## Plugins -K9s allows you to extend your command line and tooling by defining your very own cluster commands via plugins. K9s will look at `$HOME/.k9s/plugin.yml` to locate all available plugins. A plugin is defined as follows: +K9s allows you to extend your command line and tooling by defining your very own cluster commands via plugins. K9s will look at `$HOME/.config/k9s/plugin.yml` to locate all available plugins. A plugin is defined as follows: * Shortcut option represents the key combination a user would type to activate the plugin * Confirm option (when enabled) lets you see the command that is going to be executed and gives you an option to confirm or prevent execution @@ -493,7 +497,7 @@ K9s does provide additional environment variables for you to customize your plug This defines a plugin for viewing logs on a selected pod using `ctrl-l` for shortcut. ```yaml -# $HOME/.k9s/plugin.yml +# $HOME/.config/k9s/plugin.yml plugin: # Defines a plugin to provide a `ctrl-l` shortcut to tail the logs while in pod view. fred: @@ -531,12 +535,12 @@ Initially, the benchmarks will run with the following defaults: * HTTP Verb: GET * Path: / -The PortForward view is backed by a new K9s config file namely: `$HOME/.k9s/bench-.yml` (note: extension is `yml` and not `yaml`). Each cluster you connect to will have its own bench config file, containing the name of the K8s context for the cluster. Changes to this file should automatically update the PortForward view to indicate how you want to run your benchmarks. +The PortForward view is backed by a new K9s config file namely: `$HOME/.config/k9s/bench-.yml` (note: extension is `yml` and not `yaml`). Each cluster you connect to will have its own bench config file, containing the name of the K8s context for the cluster. Changes to this file should automatically update the PortForward view to indicate how you want to run your benchmarks. Here is a sample benchmarks.yml configuration. Please keep in mind this file will likely change in subsequent releases! ```yaml -# This file resides in $HOME/.k9s/bench-mycontext.yml +# This file resides in $HOME/.config/k9s/bench-mycontext.yml benchmarks: # Indicates the default concurrency and number of requests setting if a container or service rule does not match. defaults: @@ -684,9 +688,9 @@ Example: Dracula Skin ;) Dracula Skin -You can style K9s based on your own sense of look and style. Skins are YAML files, that enable a user to change the K9s presentation layer. K9s skins are loaded from `$HOME/.k9s/skin.yml`. If a skin file is detected then the skin would be loaded if not the current stock skin remains in effect. +You can style K9s based on your own sense of look and style. Skins are YAML files, that enable a user to change the K9s presentation layer. K9s skins are loaded from `$HOME/.config/k9s/skin.yml`. If a skin file is detected then the skin would be loaded if not the current stock skin remains in effect. -You can also change K9s skins based on the cluster you are connecting too. In this case, you can specify the skin file name as `$HOME/.k9s/mycontext_skin.yml` +You can also change K9s skins based on the cluster you are connecting too. In this case, you can specify the skin file name as `$HOME/.config/k9s/mycontext_skin.yml` Below is a sample skin file, more skins are available in the skins directory in this repo, just simply copy any of these in your user's home dir as `skin.yml`. Colors can be defined by name or using a hex representation. Of recent, we've added a color named `default` to indicate a transparent background color to preserve your terminal background color settings if so desired. diff --git a/go.mod b/go.mod index 59c24c0e75..14c3d321be 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ replace ( require ( github.com/atotto/clipboard v0.1.4 + github.com/adrg/xdg v0.3.0 github.com/cenkalti/backoff v2.2.1+incompatible github.com/cenkalti/backoff/v4 v4.1.0 github.com/derailed/popeye v0.9.0 diff --git a/go.sum b/go.sum index 57e828e94f..15a73d8422 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,8 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/adrg/xdg v0.3.0 h1:BO+k4wFj0IoTolBF1Apn8oZrX3LQrEbBA8+/9vyW9J4= +github.com/adrg/xdg v0.3.0/go.mod h1:7I2hH/IT30IsupOpKZ5ue7/qNi3CoKzD6tL3HwpaRMQ= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= diff --git a/go_BACKUP_36796.mod b/go_BACKUP_36796.mod new file mode 100644 index 0000000000..f859d44f29 --- /dev/null +++ b/go_BACKUP_36796.mod @@ -0,0 +1,53 @@ +module github.com/derailed/k9s + +go 1.16 + +replace ( + github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d + github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible + github.com/gdamore/tcell/v2 => github.com/derailed/tcell/v2 v2.3.1-rc.2 +) + +require ( +<<<<<<< HEAD + github.com/atotto/clipboard v0.1.4 +======= + github.com/Azure/go-autorest v14.0.0+incompatible // indirect + github.com/adrg/xdg v0.3.0 + github.com/atotto/clipboard v0.1.2 +>>>>>>> 0bf0b671 (Make k9s configuration compatible with XDG Base Directory Specification to not pollute user home directories.) + github.com/cenkalti/backoff v2.2.1+incompatible + github.com/cenkalti/backoff/v4 v4.1.0 + github.com/derailed/popeye v0.9.0 + github.com/derailed/tview v0.6.1 + github.com/drone/envsubst v1.0.2 // indirect + github.com/emicklei/go-restful v2.15.0+incompatible // indirect + github.com/fatih/color v1.10.0 + github.com/fsnotify/fsnotify v1.4.9 + github.com/fvbommel/sortorder v1.0.2 + github.com/gdamore/tcell/v2 v2.3.1 + github.com/ghodss/yaml v1.0.0 + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-runewidth v0.0.12 + github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec + github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c + github.com/openfaas/faas-provider v0.15.0 + github.com/petergtz/pegomock v2.9.0+incompatible + github.com/rakyll/hey v0.1.4 + github.com/rs/zerolog v1.22.0 + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/sahilm/fuzzy v0.1.0 + github.com/spf13/cobra v1.1.3 + github.com/stretchr/testify v1.7.0 + golang.org/x/text v0.3.6 + gopkg.in/yaml.v2 v2.4.0 + helm.sh/helm/v3 v3.5.3 + k8s.io/api v0.20.5 + k8s.io/apimachinery v0.20.5 + k8s.io/cli-runtime v0.20.5 + k8s.io/client-go v0.20.5 + k8s.io/klog/v2 v2.8.0 + k8s.io/kubectl v0.20.5 + k8s.io/metrics v0.20.5 + sigs.k8s.io/yaml v1.2.0 +) diff --git a/go_BASE_36796.mod b/go_BASE_36796.mod new file mode 100644 index 0000000000..dab5309af1 --- /dev/null +++ b/go_BASE_36796.mod @@ -0,0 +1,48 @@ +module github.com/derailed/k9s + +go 1.15 + +require ( + github.com/Azure/go-autorest v14.0.0+incompatible // indirect + github.com/atotto/clipboard v0.1.2 + github.com/cenkalti/backoff v2.2.1+incompatible + github.com/cenkalti/backoff/v4 v4.1.0 + github.com/derailed/popeye v0.9.0 + github.com/derailed/tview v0.4.9 + github.com/drone/envsubst v1.0.2 // indirect + github.com/fatih/color v1.10.0 + github.com/fsnotify/fsnotify v1.4.9 + github.com/fvbommel/sortorder v1.0.2 + github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591 + github.com/ghodss/yaml v1.0.0 + github.com/golang/protobuf v1.4.2 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-runewidth v0.0.9 + github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec + github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c + github.com/openfaas/faas-provider v0.15.0 + github.com/petergtz/pegomock v2.7.0+incompatible + github.com/rakyll/hey v0.1.4 + github.com/rs/zerolog v1.20.0 + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/sahilm/fuzzy v0.1.0 + github.com/spf13/cobra v1.1.1 + github.com/stretchr/testify v1.6.1 + golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 // indirect + golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 // indirect + golang.org/x/text v0.3.2 + google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587 // indirect + google.golang.org/grpc v1.29.1 // indirect + gopkg.in/yaml.v2 v2.2.8 + helm.sh/helm/v3 v3.2.0 + k8s.io/api v0.18.8 + k8s.io/apimachinery v0.18.8 + k8s.io/cli-runtime v0.18.8 + k8s.io/client-go v0.18.8 + k8s.io/klog v1.0.0 + k8s.io/kubectl v0.18.2 + k8s.io/metrics v0.18.8 + rsc.io/letsencrypt v0.0.3 // indirect + sigs.k8s.io/yaml v1.2.0 + vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect +) diff --git a/go_LOCAL_36796.mod b/go_LOCAL_36796.mod new file mode 100644 index 0000000000..559f0a1aba --- /dev/null +++ b/go_LOCAL_36796.mod @@ -0,0 +1,47 @@ +module github.com/derailed/k9s + +go 1.16 + +replace ( + github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d + github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible + github.com/gdamore/tcell/v2 => github.com/derailed/tcell/v2 v2.3.1-rc.2 +) + +require ( + github.com/atotto/clipboard v0.1.4 + github.com/cenkalti/backoff v2.2.1+incompatible + github.com/cenkalti/backoff/v4 v4.1.0 + github.com/derailed/popeye v0.9.0 + github.com/derailed/tview v0.6.1 + github.com/drone/envsubst v1.0.2 // indirect + github.com/emicklei/go-restful v2.15.0+incompatible // indirect + github.com/fatih/color v1.10.0 + github.com/fsnotify/fsnotify v1.4.9 + github.com/fvbommel/sortorder v1.0.2 + github.com/gdamore/tcell/v2 v2.3.1 + github.com/ghodss/yaml v1.0.0 + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-runewidth v0.0.12 + github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec + github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c + github.com/openfaas/faas-provider v0.15.0 + github.com/petergtz/pegomock v2.9.0+incompatible + github.com/rakyll/hey v0.1.4 + github.com/rs/zerolog v1.22.0 + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/sahilm/fuzzy v0.1.0 + github.com/spf13/cobra v1.1.3 + github.com/stretchr/testify v1.7.0 + golang.org/x/text v0.3.6 + gopkg.in/yaml.v2 v2.4.0 + helm.sh/helm/v3 v3.5.3 + k8s.io/api v0.20.5 + k8s.io/apimachinery v0.20.5 + k8s.io/cli-runtime v0.20.5 + k8s.io/client-go v0.20.5 + k8s.io/klog/v2 v2.8.0 + k8s.io/kubectl v0.20.5 + k8s.io/metrics v0.20.5 + sigs.k8s.io/yaml v1.2.0 +) diff --git a/go_REMOTE_36796.mod b/go_REMOTE_36796.mod new file mode 100644 index 0000000000..5576c1bad7 --- /dev/null +++ b/go_REMOTE_36796.mod @@ -0,0 +1,49 @@ +module github.com/derailed/k9s + +go 1.15 + +require ( + github.com/Azure/go-autorest v14.0.0+incompatible // indirect + github.com/adrg/xdg v0.3.0 + github.com/atotto/clipboard v0.1.2 + github.com/cenkalti/backoff v2.2.1+incompatible + github.com/cenkalti/backoff/v4 v4.1.0 + github.com/derailed/popeye v0.9.0 + github.com/derailed/tview v0.4.9 + github.com/drone/envsubst v1.0.2 // indirect + github.com/fatih/color v1.10.0 + github.com/fsnotify/fsnotify v1.4.9 + github.com/fvbommel/sortorder v1.0.2 + github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591 + github.com/ghodss/yaml v1.0.0 + github.com/golang/protobuf v1.4.2 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-runewidth v0.0.9 + github.com/openfaas/faas v0.0.0-20200207215241-6afae214e3ec + github.com/openfaas/faas-cli v0.0.0-20200124160744-30b7cec9634c + github.com/openfaas/faas-provider v0.15.0 + github.com/petergtz/pegomock v2.7.0+incompatible + github.com/rakyll/hey v0.1.4 + github.com/rs/zerolog v1.20.0 + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/sahilm/fuzzy v0.1.0 + github.com/spf13/cobra v1.1.1 + github.com/stretchr/testify v1.6.1 + golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 // indirect + golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 // indirect + golang.org/x/text v0.3.2 + google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587 // indirect + google.golang.org/grpc v1.29.1 // indirect + gopkg.in/yaml.v2 v2.2.8 + helm.sh/helm/v3 v3.2.0 + k8s.io/api v0.18.8 + k8s.io/apimachinery v0.18.8 + k8s.io/cli-runtime v0.18.8 + k8s.io/client-go v0.18.8 + k8s.io/klog v1.0.0 + k8s.io/kubectl v0.18.2 + k8s.io/metrics v0.18.8 + rsc.io/letsencrypt v0.0.3 // indirect + sigs.k8s.io/yaml v1.2.0 + vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect +) diff --git a/internal/config/config.go b/internal/config/config.go index a940c23d7b..30746499ec 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,14 +12,13 @@ import ( "gopkg.in/yaml.v2" v1 "k8s.io/api/core/v1" "k8s.io/cli-runtime/pkg/genericclioptions" + "github.com/adrg/xdg" ) // K9sConfig represents K9s configuration dir env var. const K9sConfig = "K9SCONFIG" var ( - // DefaultK9sHome represent K9s home directory. - DefaultK9sHome = filepath.Join(mustK9sHome(), ".k9s") // K9sConfigFile represents K9s config file location. K9sConfigFile = filepath.Join(K9sHome(), "config.yml") // K9sLogs represents K9s log. @@ -61,8 +60,12 @@ func K9sHome() string { if env := os.Getenv(K9sConfig); env != "" { return env } + xdgK9sHome, err := xdg.ConfigFile("k9s") + if err != nil { + log.Fatal().Err(err).Msg("Unable to create configuration directory for k9s") + } - return DefaultK9sHome + return xdgK9sHome } // NewConfig creates a new default config. diff --git a/internal/config/helpers.go b/internal/config/helpers.go index e30599cd71..77f6fe7dbb 100644 --- a/internal/config/helpers.go +++ b/internal/config/helpers.go @@ -37,14 +37,6 @@ func InNSList(nn []interface{}, ns string) bool { return InList(ss, ns) } -func mustK9sHome() string { - usr, err := user.Current() - if err != nil { - log.Fatal().Err(err).Msg("Die on retrieving user home") - } - return usr.HomeDir -} - // MustK9sUser establishes current user identity or fail. func MustK9sUser() string { usr, err := user.Current()