Skip to content

Commit

Permalink
feat: switch config file to XDG conform location
Browse files Browse the repository at this point in the history
The config file is now located in an folder according to the XDG
specification (`XDG_CONFIG_HOME`).

Since this is a breaking change, there is a check in place, which
informs the end user to please migrate to the new config location, if
the a file at the old config path has been located.

This fixes k8sgpt-ai#235.

Signed-off-by: Patrick Pichler <git@patrickpichler.dev>
  • Loading branch information
Patrick Pichler committed Apr 10, 2023
1 parent ba01bd4 commit b25294a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 18 deletions.
28 changes: 18 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ brew install k8sgpt
<!---x-release-please-end-->

**64 bit:**

<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.2.0/k8sgpt_amd64.rpm
Expand All @@ -54,7 +54,7 @@ brew install k8sgpt
```
<!---x-release-please-end-->
**64 bit:**

<!---x-release-please-start-version-->
```
curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.2.0/k8sgpt_amd64.deb
Expand Down Expand Up @@ -88,7 +88,7 @@ brew install k8sgpt
When installing Homebrew on WSL or Linux, you may encounter the following error:

```
==> Installing k8sgpt from k8sgpt-ai/k8sgpt Error: The following formula cannot be installed from a bottle and must be
==> Installing k8sgpt from k8sgpt-ai/k8sgpt Error: The following formula cannot be installed from a bottle and must be
built from the source. k8sgpt Install Clang or run brew install gcc.
```

Expand All @@ -102,7 +102,7 @@ If you install gcc as suggested, the problem will persist. Therefore, you need t

## Windows

* Download the latest Windows binaries of **k8sgpt** from the [Release](https://github.com/k8sgpt-ai/k8sgpt/releases)
* Download the latest Windows binaries of **k8sgpt** from the [Release](https://github.com/k8sgpt-ai/k8sgpt/releases)
tab based on your system architecture.
* Extract the downloaded package to your desired location. Configure the system *path* variable with the binary location

Expand All @@ -117,7 +117,7 @@ If you install gcc as suggested, the problem will persist. Therefore, you need t

* Currently the default AI provider is OpenAI, you will need to generate an API key from [OpenAI](https://openai.com)
* You can do this by running `k8sgpt generate` to open a browser link to generate it
* Run `k8sgpt auth` to set it in k8sgpt.
* Run `k8sgpt auth` to set it in k8sgpt.
* You can provide the password directly using the `--password` flag.
* Run `k8sgpt filters` to manage the active filters used by the analyzer. By default, all filters are executed during analysis.
* Run `k8sgpt analyze` to run a scan.
Expand All @@ -127,7 +127,7 @@ If you install gcc as suggested, the problem will persist. Therefore, you need t

## Analyzers

K8sGPT uses analyzers to triage and diagnose issues in your cluster. It has a set of analyzers that are built in, but
K8sGPT uses analyzers to triage and diagnose issues in your cluster. It has a set of analyzers that are built in, but
you will be able to write your own analyzers.

### Built in analyzers
Expand Down Expand Up @@ -235,17 +235,25 @@ k8sgpt analyze --explain --filter=Service --output=json

## What about kubectl-ai?

The kubectl-ai [project](https://github.com/sozercan/kubectl-ai) uses AI to create manifests and apply them to the
The kubectl-ai [project](https://github.com/sozercan/kubectl-ai) uses AI to create manifests and apply them to the
cluster. It is not what we are trying to do here, it is focusing on writing YAML manifests.

K8sgpt is focused on triaging and diagnosing issues in your cluster. It is a tool for SRE, Platform & DevOps engineers
to help them understand what is going on in their cluster. Cutting through the noise of logs and multiple tools to find
K8sgpt is focused on triaging and diagnosing issues in your cluster. It is a tool for SRE, Platform & DevOps engineers
to help them understand what is going on in their cluster. Cutting through the noise of logs and multiple tools to find
the root cause of an issue.


## Configuration

`k8sgpt` stores config data in `~/.k8sgpt.yaml` the data is stored in plain text, including your OpenAI key.
`k8sgpt` stores config data in the `$XDG_CONFIG_HOME/k8sgpt/k8sgpt.yaml` file. The data is stored in plain text, including your OpenAI key.

Config file locations:
| OS | Path |
|---------|--------------------------------------------------|
| MacOS | ~/Library/Application Support/k8sgpt/k8sgpt.yaml |
| Linux | ~/.config/k8sgpt/k8sgpt.yaml |
| Windows | %LOCALAPPDATA%/k8sgpt/k8sgpt.yaml |


## Contributing

Expand Down
54 changes: 46 additions & 8 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package cmd

import (
"errors"
"fmt"
"os"
"path/filepath"

"github.com/k8sgpt-ai/k8sgpt/cmd/filters"
"github.com/k8sgpt-ai/k8sgpt/cmd/generate"
"k8s.io/client-go/util/homedir"

"github.com/adrg/xdg"
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/cmd/analyze"
"github.com/k8sgpt-ai/k8sgpt/cmd/auth"
Expand Down Expand Up @@ -44,6 +47,8 @@ func Execute(v string) {
}

func init() {
checkForOldConfig()

cobra.OnInitialize(initConfig)

var kubeconfigPath string
Expand All @@ -54,13 +59,12 @@ func init() {
rootCmd.AddCommand(analyze.AnalyzeCmd)
rootCmd.AddCommand(filters.FiltersCmd)
rootCmd.AddCommand(generate.GenerateCmd)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.k8sgpt.yaml)")
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", fmt.Sprintf("config file (default is %s)", getConfigFilePath()))
rootCmd.PersistentFlags().StringVar(&kubecontext, "kubecontext", "", "Kubernetes context to use. Only required if out-of-cluster.")
rootCmd.PersistentFlags().StringVar(&kubeconfig, "kubeconfig", kubeconfigPath, "Path to a kubeconfig. Only required if out-of-cluster.")
// Cobra also supports local flags, which will only run
// when this action is called directly.
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

}

// initConfig reads in config file and ENV variables if set.
Expand All @@ -69,14 +73,14 @@ func initConfig() {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := os.UserHomeDir()
cobra.CheckErr(err)
// the config will belocated under `~/.config/k8sgpt/k8sgpt.yaml` on linux
configDir := filepath.Join(xdg.ConfigHome, "k8sgpt")

ensureDirExists(configDir)

// Search config in home directory with name ".k8sgpt.git" (without extension).
viper.AddConfigPath(home)
viper.AddConfigPath(configDir)
viper.SetConfigType("yaml")
viper.SetConfigName(".k8sgpt")
viper.SetConfigName("k8sgpt")

viper.SafeWriteConfig()
}
Expand All @@ -97,3 +101,37 @@ func initConfig() {
// fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
}
}

func getConfigFilePath() string {
return filepath.Join(xdg.ConfigHome, "k8sgpt", "k8sgpt.yaml")
}

func ensureDirExists(dir string) {
err := os.Mkdir(dir, 0755)

if errors.Is(err, os.ErrExist) {
return
}
}

// tests if a file exists in the legacy config path and warns the user about it
func checkForOldConfig() {
home, err := os.UserHomeDir()

// ignoring the error here, as we do not want to exit here even on error
if err != nil {
return
}

oldConfig := filepath.Join(home, ".k8sgpt.yaml")

if _, err := os.Stat(oldConfig); err == nil {
fmt.Fprintln(os.Stderr, color.RedString("Warning: Legacy config file at `%s` detected!", oldConfig))
fmt.Fprintln(os.Stderr, color.RedString("Please migrate to new config file location `%s`", getConfigFilePath()))
} else if errors.Is(err, os.ErrNotExist) {
// old config file is not existing, exactly what we want
return
} else {
fmt.Fprintln(os.Stderr, color.RedString("error while checking for existance of old config file: %s\n", err))
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
)

require (
github.com/adrg/xdg v0.4.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
Expand Down Expand Up @@ -407,6 +409,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down

0 comments on commit b25294a

Please sign in to comment.