add support for replacing config after node starts
- TODO: does a "locked repo" need fine-grained (i.e. field-level) locking?
This commit is contained in:
parent
2d6b2e3811
commit
cf321f7667
@ -412,7 +412,7 @@ func Repo(r repo.Repo) Option {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c, err := lr.GetConfig()
|
c, err := lr.Config()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
fslock "github.com/ipfs/go-fs-lock"
|
fslock "github.com/ipfs/go-fs-lock"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
@ -271,6 +272,29 @@ func (fsr *fsLockedRepo) Config() (interface{}, error) {
|
|||||||
return config.FromFile(fsr.join(fsConfig), defConfForType(fsr.repoType))
|
return config.FromFile(fsr.join(fsConfig), defConfForType(fsr.repoType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fsr *fsLockedRepo) SetConfig(cfg interface{}) error {
|
||||||
|
if err := fsr.stillValid(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp, err := ioutil.TempFile("", "lotus-config-temp")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = toml.NewEncoder(tmp).Encode(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Rename(tmp.Name(), fsr.join(fsConfig))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (fsr *fsLockedRepo) GetStorage() (stores.StorageConfig, error) {
|
func (fsr *fsLockedRepo) GetStorage() (stores.StorageConfig, error) {
|
||||||
fsr.storageLk.Lock()
|
fsr.storageLk.Lock()
|
||||||
defer fsr.storageLk.Unlock()
|
defer fsr.storageLk.Unlock()
|
||||||
|
@ -37,7 +37,8 @@ type LockedRepo interface {
|
|||||||
Datastore(namespace string) (datastore.Batching, error)
|
Datastore(namespace string) (datastore.Batching, error)
|
||||||
|
|
||||||
// Returns config in this repo
|
// Returns config in this repo
|
||||||
GetConfig() (interface{}, error)
|
Config() (interface{}, error)
|
||||||
|
SetConfig(interface{}) error
|
||||||
|
|
||||||
GetStorage() (stores.StorageConfig, error)
|
GetStorage() (stores.StorageConfig, error)
|
||||||
SetStorage(func(*stores.StorageConfig)) error
|
SetStorage(func(*stores.StorageConfig)) error
|
||||||
|
@ -30,8 +30,13 @@ type MemRepo struct {
|
|||||||
token *byte
|
token *byte
|
||||||
|
|
||||||
datastore datastore.Datastore
|
datastore datastore.Datastore
|
||||||
configF func(t RepoType) interface{}
|
|
||||||
keystore map[string]types.KeyInfo
|
keystore map[string]types.KeyInfo
|
||||||
|
|
||||||
|
// given a repo type, produce the default config
|
||||||
|
configF func(t RepoType) interface{}
|
||||||
|
|
||||||
|
// holds the current config value
|
||||||
|
config interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type lockedMemRepo struct {
|
type lockedMemRepo struct {
|
||||||
@ -217,11 +222,22 @@ func (lmem *lockedMemRepo) Datastore(ns string) (datastore.Batching, error) {
|
|||||||
return namespace.Wrap(lmem.mem.datastore, datastore.NewKey(ns)), nil
|
return namespace.Wrap(lmem.mem.datastore, datastore.NewKey(ns)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lmem *lockedMemRepo) GetConfig() (interface{}, error) {
|
func (lmem *lockedMemRepo) Config() (interface{}, error) {
|
||||||
if err := lmem.checkToken(); err != nil {
|
if err := lmem.checkToken(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return lmem.mem.configF(lmem.t), nil
|
|
||||||
|
if lmem.mem.config == nil {
|
||||||
|
lmem.mem.config = lmem.mem.configF(lmem.t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lmem.mem.config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lmem *lockedMemRepo) SetConfig(cfg interface{}) error {
|
||||||
|
lmem.mem.config = cfg
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lmem *lockedMemRepo) Storage() (stores.StorageConfig, error) {
|
func (lmem *lockedMemRepo) Storage() (stores.StorageConfig, error) {
|
||||||
|
@ -9,6 +9,8 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/node/config"
|
"github.com/filecoin-project/lotus/node/config"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func basicTest(t *testing.T, repo Repo) {
|
func basicTest(t *testing.T, repo Repo) {
|
||||||
@ -47,10 +49,22 @@ func basicTest(t *testing.T, repo Repo) {
|
|||||||
assert.NoError(t, err, "setting multiaddr shouldn't error")
|
assert.NoError(t, err, "setting multiaddr shouldn't error")
|
||||||
assert.Equal(t, ma, apima, "returned API multiaddr should be the same")
|
assert.Equal(t, ma, apima, "returned API multiaddr should be the same")
|
||||||
|
|
||||||
cfg, err := lrepo.Config()
|
c1, err := lrepo.Config()
|
||||||
assert.Equal(t, config.DefaultFullNode(), cfg, "there should be a default config")
|
assert.Equal(t, config.DefaultFullNode(), c1, "there should be a default config")
|
||||||
assert.NoError(t, err, "config should not error")
|
assert.NoError(t, err, "config should not error")
|
||||||
|
|
||||||
|
// mutate config and persist back to repo
|
||||||
|
cfg1 := c1.(*config.FullNode)
|
||||||
|
cfg1.Client.IpfsMAddr = "duvall"
|
||||||
|
err = lrepo.SetConfig(cfg1)
|
||||||
|
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()
|
err = lrepo.Close()
|
||||||
assert.NoError(t, err, "should be able to close")
|
assert.NoError(t, err, "should be able to close")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user