config: --config "" or "/notfound" for in memory config only #4996

If `--config` is set to empty string or the special value `/notfound`
then rclone will keep the config file in memory only.
This commit is contained in:
Nick Craig-Wood 2021-03-13 12:36:38 +00:00
parent 46078d391f
commit bb0b6432ae
4 changed files with 54 additions and 2 deletions

View File

@ -554,6 +554,9 @@ location is for you.
Use this flag to override the config location, e.g. `rclone
--config=".myconfig" .config`.
If this is set to empty string or the special value `/notfound` then
rclone will keep the config file in memory only.
### --contimeout=TIME ###
Set the connection timeout. This should be in go time format which

View File

@ -242,8 +242,7 @@ func SaveConfig() {
waitingTimeMs := mathrand.Intn(1000)
time.Sleep(time.Duration(waitingTimeMs) * time.Millisecond)
}
log.Fatalf("Failed to save config after %d tries: %v", ci.LowLevelRetries, err)
fs.Errorf(nil, "Failed to save config after %d tries: %v", ci.LowLevelRetries, err)
return
}

View File

@ -15,6 +15,9 @@ import (
"github.com/rclone/rclone/fs/config"
)
// Special value indicating in memory config file. Empty string works also.
const noConfigFile = "/notfound"
// LoadConfig installs the config file handler and calls config.LoadConfig
func LoadConfig(ctx context.Context) {
config.Data = &Storage{}
@ -29,11 +32,20 @@ type Storage struct {
fi os.FileInfo // stat of the file when last loaded
}
// Return whether we have a real config file or not
func (s *Storage) noConfig() bool {
return config.ConfigPath == "" || config.ConfigPath == noConfigFile
}
// Check to see if we need to reload the config
func (s *Storage) check() {
s.mu.Lock()
defer s.mu.Unlock()
if s.noConfig() {
return
}
// Check to see if config file has changed since it was last loaded
fi, err := os.Stat(config.ConfigPath)
if err == nil {
@ -59,6 +71,10 @@ func (s *Storage) _load() (err error) {
}
}()
if s.noConfig() {
return config.ErrorConfigFileNotFound
}
fd, err := os.Open(config.ConfigPath)
if err != nil {
if os.IsNotExist(err) {
@ -97,6 +113,10 @@ func (s *Storage) Save() error {
s.mu.Lock()
defer s.mu.Unlock()
if s.noConfig() {
return nil
}
dir, name := filepath.Split(config.ConfigPath)
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {

View File

@ -213,3 +213,33 @@ func TestConfigFileDoesNotExist(t *testing.T) {
assert.False(t, ok)
assert.Equal(t, "", value)
}
func testConfigFileNoConfig(t *testing.T, configPath string) {
config.ConfigPath = configPath
data := &Storage{}
err := data.Load()
require.Equal(t, config.ErrorConfigFileNotFound, err)
data.SetValue("one", "extra", "42")
value, ok := data.GetValue("one", "extra")
assert.True(t, ok)
assert.Equal(t, "42", value)
err = data.Save()
require.NoError(t, err)
}
func TestConfigFileNoConfig(t *testing.T) {
old := config.ConfigPath
defer func() {
config.ConfigPath = old
}()
t.Run("Empty", func(t *testing.T) {
testConfigFileNoConfig(t, "")
})
t.Run("NotFound", func(t *testing.T) {
testConfigFileNoConfig(t, "/notfound")
})
}