Merge pull request #1966 from laser/feat/reload-config

expose config-setting through Repo interface
This commit is contained in:
Łukasz Magiera 2020-06-11 18:15:06 +02:00 committed by GitHub
commit 1c583ab487
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 10 deletions

View File

@ -12,7 +12,7 @@ import (
)
// FromFile loads config from a specified file overriding defaults specified in
// the def parameter. If file does not exist or is empty defaults are asummed.
// the def parameter. If file does not exist or is empty defaults are assumed.
func FromFile(path string, def interface{}) (interface{}, error) {
file, err := os.Open(path)
switch {

View File

@ -11,6 +11,7 @@ import (
"strings"
"sync"
"github.com/BurntSushi/toml"
"github.com/ipfs/go-datastore"
fslock "github.com/ipfs/go-fs-lock"
logging "github.com/ipfs/go-log/v2"
@ -229,6 +230,7 @@ type fsLockedRepo struct {
dsOnce sync.Once
storageLk sync.Mutex
configLk sync.Mutex
}
func (fsr *fsLockedRepo) Path() string {
@ -265,12 +267,50 @@ func (fsr *fsLockedRepo) stillValid() error {
}
func (fsr *fsLockedRepo) Config() (interface{}, error) {
if err := fsr.stillValid(); err != nil {
return nil, err
}
fsr.configLk.Lock()
defer fsr.configLk.Unlock()
return fsr.loadConfigFromDisk()
}
func (fsr *fsLockedRepo) loadConfigFromDisk() (interface{}, error) {
return config.FromFile(fsr.join(fsConfig), defConfForType(fsr.repoType))
}
func (fsr *fsLockedRepo) SetConfig(c func(interface{})) error {
if err := fsr.stillValid(); err != nil {
return err
}
fsr.configLk.Lock()
defer fsr.configLk.Unlock()
cfg, err := fsr.loadConfigFromDisk()
if err != nil {
return err
}
// mutate in-memory representation of config
c(cfg)
// buffer into which we write TOML bytes
buf := new(bytes.Buffer)
// encode now-mutated config as TOML and write to buffer
err = toml.NewEncoder(buf).Encode(cfg)
if err != nil {
return err
}
// write buffer of TOML bytes to config file
err = ioutil.WriteFile(fsr.join(fsConfig), buf.Bytes(), 0644)
if err != nil {
return err
}
return nil
}
func (fsr *fsLockedRepo) GetStorage() (stores.StorageConfig, error) {
fsr.storageLk.Lock()
defer fsr.storageLk.Unlock()

View File

@ -38,6 +38,7 @@ type LockedRepo interface {
// Returns config in this repo
Config() (interface{}, error)
SetConfig(func(interface{})) error
GetStorage() (stores.StorageConfig, error)
SetStorage(func(*stores.StorageConfig)) error

View File

@ -30,8 +30,16 @@ type MemRepo struct {
token *byte
datastore datastore.Datastore
configF func(t RepoType) interface{}
keystore map[string]types.KeyInfo
// given a repo type, produce the default config
configF func(t RepoType) interface{}
// holds the current config value
config struct {
sync.Mutex
val interface{}
}
}
type lockedMemRepo struct {
@ -45,6 +53,10 @@ type lockedMemRepo struct {
}
func (lmem *lockedMemRepo) GetStorage() (stores.StorageConfig, error) {
if err := lmem.checkToken(); err != nil {
return stores.StorageConfig{}, err
}
if lmem.sc == nil {
lmem.sc = &stores.StorageConfig{StoragePaths: []stores.LocalPath{
{Path: lmem.Path()},
@ -55,6 +67,10 @@ func (lmem *lockedMemRepo) GetStorage() (stores.StorageConfig, error) {
}
func (lmem *lockedMemRepo) SetStorage(c func(*stores.StorageConfig)) error {
if err := lmem.checkToken(); err != nil {
return err
}
_, _ = lmem.GetStorage()
c(lmem.sc)
@ -221,11 +237,32 @@ func (lmem *lockedMemRepo) Config() (interface{}, error) {
if err := lmem.checkToken(); err != nil {
return nil, err
}
return lmem.mem.configF(lmem.t), nil
lmem.mem.config.Lock()
defer lmem.mem.config.Unlock()
if lmem.mem.config.val == nil {
lmem.mem.config.val = lmem.mem.configF(lmem.t)
}
return lmem.mem.config.val, nil
}
func (lmem *lockedMemRepo) Storage() (stores.StorageConfig, error) {
panic("implement me")
func (lmem *lockedMemRepo) SetConfig(c func(interface{})) error {
if err := lmem.checkToken(); err != nil {
return err
}
lmem.mem.config.Lock()
defer lmem.mem.config.Unlock()
if lmem.mem.config.val == nil {
lmem.mem.config.val = lmem.mem.configF(lmem.t)
}
c(lmem.mem.config.val)
return nil
}
func (lmem *lockedMemRepo) SetAPIEndpoint(ma multiaddr.Multiaddr) error {

View File

@ -9,6 +9,8 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/config"
"github.com/stretchr/testify/require"
)
func basicTest(t *testing.T, repo Repo) {
@ -47,10 +49,23 @@ func basicTest(t *testing.T, repo Repo) {
assert.NoError(t, err, "setting multiaddr shouldn't error")
assert.Equal(t, ma, apima, "returned API multiaddr should be the same")
cfg, err := lrepo.Config()
assert.Equal(t, config.DefaultFullNode(), cfg, "there should be a default config")
c1, err := lrepo.Config()
assert.Equal(t, config.DefaultFullNode(), c1, "there should be a default config")
assert.NoError(t, err, "config should not error")
// mutate config and persist back to repo
err = lrepo.SetConfig(func(c interface{}) {
cfg := c.(*config.FullNode)
cfg.Client.IpfsMAddr = "duvall"
})
assert.NoError(t, err)
// load config and verify changes
c2, err := lrepo.Config()
require.NoError(t, err)
cfg2 := c2.(*config.FullNode)
require.Equal(t, cfg2.Client.IpfsMAddr, "duvall")
err = lrepo.Close()
assert.NoError(t, err, "should be able to close")