Merge pull request #1966 from laser/feat/reload-config
expose config-setting through Repo interface
This commit is contained in:
commit
1c583ab487
@ -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 {
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user