set repository config location w.r.t corso config location (#4638)
Create repository config(s) in the same parent directory as corso config instead of creating repository config in `/tmp` directory.
Scenarios:
1. CORSO_CONFIG_DIR set to /test/directory, --config-file not provided
- `.corso.toml` should be created at /test/directory
- `repository.config` should be created at /test/directory
2. CORSO_CONFIG_DIR not set, --config-file provided /test/directory-2
- `.corso.toml` should be created at /test/directory-2
- `repository.config` should be created at /test/directory-2
3. CORSO_CONFIG_DIR not set, --config-file not provided
- `.corso.toml` should be created at /home/user
- `repository.config` should be created at /home/user
#### Does this PR need a docs update or release note?
- [ ] ✅ Yes, it's included
- [x] 🕐 Yes, but in a later PR
- [ ] ⛔ No
#### Type of change
<!--- Please check the type of change your PR introduces: --->
- [ ] 🌻 Feature
- [x] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup
#### Issue(s)
* #4443
#### Test Plan
<!-- How will this be tested prior to merging.-->
- [x] 💪 Manual
- [x] ⚡ Unit test
- [x] 💚 E2E
This commit is contained in:
parent
73112f695b
commit
0b997e6176
@ -2,6 +2,8 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
@ -73,8 +75,8 @@ func init() {
|
|||||||
|
|
||||||
// adds the persistent flag --config-file to the provided command.
|
// adds the persistent flag --config-file to the provided command.
|
||||||
func AddConfigFlags(cmd *cobra.Command) {
|
func AddConfigFlags(cmd *cobra.Command) {
|
||||||
fs := cmd.PersistentFlags()
|
pf := cmd.PersistentFlags()
|
||||||
fs.StringVar(
|
pf.StringVar(
|
||||||
&configFilePathFlag,
|
&configFilePathFlag,
|
||||||
"config-file", displayDefaultFP, "config file location")
|
"config-file", displayDefaultFP, "config file location")
|
||||||
}
|
}
|
||||||
@ -86,17 +88,22 @@ func AddConfigFlags(cmd *cobra.Command) {
|
|||||||
// InitFunc provides a func that lazily initializes viper and
|
// InitFunc provides a func that lazily initializes viper and
|
||||||
// verifies that the configuration was able to read a file.
|
// verifies that the configuration was able to read a file.
|
||||||
func InitFunc(cmd *cobra.Command, args []string) error {
|
func InitFunc(cmd *cobra.Command, args []string) error {
|
||||||
|
ctx := cmd.Context()
|
||||||
|
|
||||||
fp := configFilePathFlag
|
fp := configFilePathFlag
|
||||||
if len(fp) == 0 || fp == displayDefaultFP {
|
if len(fp) == 0 || fp == displayDefaultFP {
|
||||||
fp = configFilePath
|
fp = configFilePath
|
||||||
}
|
}
|
||||||
|
|
||||||
err := initWithViper(GetViper(cmd.Context()), fp)
|
vpr := GetViper(ctx)
|
||||||
if err != nil {
|
|
||||||
|
if err := initWithViper(vpr, fp); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return Read(cmd.Context())
|
ctx = SetViper(ctx, vpr)
|
||||||
|
|
||||||
|
return Read(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initWithViper implements InitConfig, but takes in a viper
|
// initWithViper implements InitConfig, but takes in a viper
|
||||||
@ -114,26 +121,23 @@ func initWithViper(vpr *viper.Viper, configFP string) error {
|
|||||||
vpr.AddConfigPath(configDir)
|
vpr.AddConfigPath(configDir)
|
||||||
vpr.SetConfigType("toml")
|
vpr.SetConfigType("toml")
|
||||||
vpr.SetConfigName(".corso")
|
vpr.SetConfigName(".corso")
|
||||||
|
} else {
|
||||||
|
ext := filepath.Ext(configFP)
|
||||||
|
if len(ext) == 0 {
|
||||||
|
return clues.New("config file requires an extension e.g. `toml`")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
fileName := filepath.Base(configFP)
|
||||||
|
fileName = strings.TrimSuffix(fileName, ext)
|
||||||
|
vpr.SetConfigType(strings.TrimPrefix(ext, "."))
|
||||||
|
vpr.SetConfigName(fileName)
|
||||||
|
vpr.SetConfigFile(configFP)
|
||||||
|
// We also configure the path, type and filename
|
||||||
|
// because `vpr.SafeWriteConfig` needs these set to
|
||||||
|
// work correctly (it does not use the configured file)
|
||||||
|
vpr.AddConfigPath(filepath.Dir(configFP))
|
||||||
}
|
}
|
||||||
|
|
||||||
vpr.SetConfigFile(configFP)
|
|
||||||
// We also configure the path, type and filename
|
|
||||||
// because `vpr.SafeWriteConfig` needs these set to
|
|
||||||
// work correctly (it does not use the configured file)
|
|
||||||
vpr.AddConfigPath(filepath.Dir(configFP))
|
|
||||||
|
|
||||||
ext := filepath.Ext(configFP)
|
|
||||||
if len(ext) == 0 {
|
|
||||||
return clues.New("config file requires an extension e.g. `toml`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fileName := filepath.Base(configFP)
|
|
||||||
fileName = strings.TrimSuffix(fileName, ext)
|
|
||||||
vpr.SetConfigType(strings.TrimPrefix(ext, "."))
|
|
||||||
vpr.SetConfigName(fileName)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +286,10 @@ func getStorageAndAccountWithViper(
|
|||||||
// possibly read the prior config from a .corso file
|
// possibly read the prior config from a .corso file
|
||||||
if readFromFile {
|
if readFromFile {
|
||||||
if err := vpr.ReadInConfig(); err != nil {
|
if err := vpr.ReadInConfig(); err != nil {
|
||||||
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
configNotSet := errors.As(err, &viper.ConfigFileNotFoundError{})
|
||||||
|
configNotFound := errors.Is(err, fs.ErrNotExist)
|
||||||
|
|
||||||
|
if !configNotSet && !configNotFound {
|
||||||
return config, clues.Wrap(err, "reading corso config file: "+vpr.ConfigFileUsed())
|
return config, clues.Wrap(err, "reading corso config file: "+vpr.ConfigFileUsed())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,15 +45,17 @@ func configureStorage(
|
|||||||
return store, clues.Wrap(err, "validating corso credentials")
|
return store, clues.Wrap(err, "validating corso credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configDir, _ := filepath.Split(vpr.ConfigFileUsed())
|
||||||
|
|
||||||
cCfg := storage.CommonConfig{
|
cCfg := storage.CommonConfig{
|
||||||
Corso: corso,
|
Corso: corso,
|
||||||
|
KopiaCfgDir: configDir,
|
||||||
}
|
}
|
||||||
// the following is a hack purely for integration testing.
|
// the following is a hack purely for integration testing.
|
||||||
// the value is not required, and if empty, kopia will default
|
// the value is not required, and if empty, kopia will default
|
||||||
// to its routine behavior
|
// to its routine behavior
|
||||||
if t, ok := vpr.Get("corso-testing").(bool); t && ok {
|
if t, ok := vpr.Get("corso-testing").(bool); t && ok {
|
||||||
dir, _ := filepath.Split(vpr.ConfigFileUsed())
|
cCfg.KopiaCfgDir = configDir
|
||||||
cCfg.KopiaCfgDir = dir
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure required properties are present
|
// ensure required properties are present
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user