diff --git a/repo/config/config.go b/repo/config/config.go index 898cf56a4722..b01d4ed062a1 100644 --- a/repo/config/config.go +++ b/repo/config/config.go @@ -18,7 +18,7 @@ var log = logging.Logger("config") // Config is used to load ipfs config files. type Config struct { Identity Identity // local node's peer identity - Datastore Datastore // local node's storage + Datastore *Datastore // local node's storage Addresses Addresses // local node's addresses Mounts Mounts // local node's mount points Discovery Discovery // local node's discovery mechanisms diff --git a/repo/config/datastore.go b/repo/config/datastore.go index 9c368f21f97f..697f07535ffd 100644 --- a/repo/config/datastore.go +++ b/repo/config/datastore.go @@ -1,34 +1,22 @@ package config -import ( - "encoding/json" -) - // DefaultDataStoreDirectory is the directory to store all the local IPFS data. const DefaultDataStoreDirectory = "datastore" // Datastore tracks the configuration of the datastore. type Datastore struct { - Type string - Path string StorageMax string // in B, kB, kiB, MB, ... StorageGCWatermark int64 // in percentage to multiply on StorageMax GCPeriod string // in ns, us, ms, s, m, h + Path string + NoSync bool // deprecated + + Spec map[string]interface{} - Params *json.RawMessage - NoSync bool HashOnRead bool BloomFilterSize int } -func (d *Datastore) ParamData() []byte { - if d.Params == nil { - return nil - } - - return []byte(*d.Params) -} - type S3Datastore struct { Region string `json:"region"` Bucket string `json:"bucket"` @@ -46,10 +34,6 @@ type LevelDB struct { Compression string } -type MeasureDB struct { - Label string -} - // DataStorePath returns the default data store path given a configuration root // (set an empty string to have the default configuration root) func DataStorePath(configroot string) (string, error) { diff --git a/repo/config/init.go b/repo/config/init.go index edb5408b2f37..d176bf778db1 100644 --- a/repo/config/init.go +++ b/repo/config/init.go @@ -76,19 +76,38 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) { return conf, nil } -func datastoreConfig() (Datastore, error) { - dspath, err := DataStorePath("") - if err != nil { - return Datastore{}, err - } - return Datastore{ - Path: dspath, - Type: "leveldb", +func datastoreConfig() (*Datastore, error) { + return &Datastore{ StorageMax: "10GB", StorageGCWatermark: 90, // 90% GCPeriod: "1h", - HashOnRead: false, BloomFilterSize: 0, + Spec: map[string]interface{}{ + "type": "mount", + "mounts": []interface{}{ + map[string]interface{}{ + "mountpoint": "/blocks", + "type": "measure", + "prefix": "flatfs.datastore", + "child": map[string]interface{}{ + "type": "flatfs", + "path": "blocks", + "nosync": false, + "prefixLen": 4, + }, + }, + map[string]interface{}{ + "mountpoint": "/", + "type": "measure", + "prefix": "leveldb.datastore", + "child": map[string]interface{}{ + "type": "levelds", + "path": "datastore", + "compression": "none", + }, + }, + }, + }, }, nil } diff --git a/repo/fsrepo/datastores.go b/repo/fsrepo/datastores.go index ff01fe60b72b..645c70c78b47 100644 --- a/repo/fsrepo/datastores.go +++ b/repo/fsrepo/datastores.go @@ -6,7 +6,6 @@ import ( "path/filepath" repo "github.com/ipfs/go-ipfs/repo" - config "github.com/ipfs/go-ipfs/repo/config" ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore" mount "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore/syncmount" @@ -16,70 +15,40 @@ import ( "gx/ipfs/Qmbx2KUs8mUbDUiiESzC1ms7mdmh4pRu8X1V1tffC46M4n/go-ds-flatfs" ) -func (r *FSRepo) constructDatastore(kind string, params []byte) (repo.Datastore, error) { - switch kind { +func (r *FSRepo) constructDatastore(params map[string]interface{}) (repo.Datastore, error) { + switch params["type"] { case "mount": - var mounts []*mountConfig - if err := json.Unmarshal(params, &mounts); err != nil { - return nil, fmt.Errorf("datastore mount: %v", err) + mounts, ok := params["mounts"].([]interface{}) + if !ok { + return nil, fmt.Errorf("mounts field wasnt an array") } return r.openMountDatastore(mounts) case "flatfs": - var flatfsparams config.FlatDS - if err := json.Unmarshal(params, &flatfsparams); err != nil { - return nil, fmt.Errorf("datastore flatfs: %v", err) - } - - return r.openFlatfsDatastore(&flatfsparams) + return r.openFlatfsDatastore(params) case "mem": return ds.NewMapDatastore(), nil case "log": - var cfg struct { - Name string - ChildType string - Child *json.RawMessage - } - - if err := json.Unmarshal(params, &cfg); err != nil { - return nil, fmt.Errorf("datastore measure: %v", err) - } - - child, err := r.constructDatastore(cfg.ChildType, []byte(*cfg.Child)) + child, err := r.constructDatastore(params["child"].(map[string]interface{})) if err != nil { return nil, err } - return ds.NewLogDatastore(child, cfg.Name), nil - + return ds.NewLogDatastore(child, params["name"].(string)), nil case "measure": - var measureOpts struct { - Prefix string - ChildType string - Child *json.RawMessage - } - - if err := json.Unmarshal(params, &measureOpts); err != nil { - return nil, fmt.Errorf("datastore measure: %v", err) - } - - child, err := r.constructDatastore(measureOpts.ChildType, []byte(*measureOpts.Child)) + child, err := r.constructDatastore(params["child"].(map[string]interface{})) if err != nil { return nil, err } - return r.openMeasureDB(measureOpts.Prefix, child) - - case "levelds": - var c config.LevelDB - if err := json.Unmarshal(params, &c); err != nil { - return nil, fmt.Errorf("datastore levelds: %v", err) - } + prefix := params["prefix"].(string) - return r.openLeveldbDatastore(&c) + return r.openMeasureDB(prefix, child) + case "levelds": + return r.openLeveldbDatastore(params) default: - return nil, fmt.Errorf("unknown datastore type: %s", kind) + return nil, fmt.Errorf("unknown datastore type: %s", params["type"]) } } @@ -89,40 +58,48 @@ type mountConfig struct { Child *json.RawMessage } -func (r *FSRepo) openMountDatastore(mountcfg []*mountConfig) (repo.Datastore, error) { +func (r *FSRepo) openMountDatastore(mountcfg []interface{}) (repo.Datastore, error) { var mounts []mount.Mount - for _, cfg := range mountcfg { + for _, iface := range mountcfg { + cfg := iface.(map[string]interface{}) - child, err := r.constructDatastore(cfg.ChildType, []byte(*cfg.Child)) + child, err := r.constructDatastore(cfg) if err != nil { return nil, err } + prefix, found := cfg["mountpoint"] + if !found { + return nil, fmt.Errorf("no 'mountpoint' on mount") + } + mounts = append(mounts, mount.Mount{ Datastore: child, - Prefix: ds.NewKey(cfg.Path), + Prefix: ds.NewKey(prefix.(string)), }) } return mount.New(mounts), nil } -func (r *FSRepo) openFlatfsDatastore(params *config.FlatDS) (repo.Datastore, error) { - p := params.Path +func (r *FSRepo) openFlatfsDatastore(params map[string]interface{}) (repo.Datastore, error) { + p := params["path"].(string) if !filepath.IsAbs(p) { p = filepath.Join(r.path, p) } - return flatfs.New(p, params.PrefixLen, params.Sync) + + plen := int(params["prefixLen"].(float64)) + return flatfs.New(p, plen, params["nosync"].(bool)) } -func (r *FSRepo) openLeveldbDatastore(params *config.LevelDB) (repo.Datastore, error) { - p := params.Path +func (r *FSRepo) openLeveldbDatastore(params map[string]interface{}) (repo.Datastore, error) { + p := params["path"].(string) if !filepath.IsAbs(p) { p = filepath.Join(r.path, p) } var c ldbopts.Compression - switch params.Compression { + switch params["compression"].(string) { case "none": c = ldbopts.NoCompression case "snappy": diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 5d8f55a5d818..d30daa4628a7 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -353,20 +353,19 @@ func (r *FSRepo) openKeystore() error { // openDatastore returns an error if the config file is not present. func (r *FSRepo) openDatastore() error { - switch r.config.Datastore.Type { - case "default", "leveldb", "": - // TODO: This is for legacy configs, remove in the future - d, err := openDefaultDatastore(r) + if r.config.Datastore.Spec != nil { + d, err := r.constructDatastore(r.config.Datastore.Spec) if err != nil { return err } + r.ds = d - default: - d, err := r.constructDatastore(r.config.Datastore.Type, r.config.Datastore.ParamData()) + } else { + // TODO: This is for legacy configs, remove in the future + d, err := openDefaultDatastore(r) if err != nil { return err } - r.ds = d }