diff --git a/config/config.go b/config/config.go index 93494265d05..bc8ea371f17 100644 --- a/config/config.go +++ b/config/config.go @@ -83,7 +83,7 @@ func Path(configroot, extension string) (string, error) { // - If the user-provided configuration file path is only a file name, use the // configuration root directory, otherwise use only the user-provided path // and ignore the configuration root. -func Filename(configroot string, userConfigFile string) (string, error) { +func Filename(configroot, userConfigFile string) (string, error) { if userConfigFile == "" { return Path(configroot, DefaultConfigFile) } diff --git a/config/types.go b/config/types.go index a781f023af9..2171a53f5bd 100644 --- a/config/types.go +++ b/config/types.go @@ -415,9 +415,9 @@ func (p OptionalString) String() string { var _ json.Unmarshaler = (*OptionalInteger)(nil) var _ json.Marshaler = (*OptionalInteger)(nil) -type swarmLimits struct{} +type swarmLimits doNotUse -var _ json.Unmarshaler = swarmLimits{} +var _ json.Unmarshaler = swarmLimits(false) func (swarmLimits) UnmarshalJSON(b []byte) error { d := json.NewDecoder(bytes.NewReader(b)) @@ -439,9 +439,9 @@ func (swarmLimits) UnmarshalJSON(b []byte) error { } } -type experimentalAcceleratedDHTClient struct{} +type experimentalAcceleratedDHTClient doNotUse -var _ json.Unmarshaler = experimentalAcceleratedDHTClient{} +var _ json.Unmarshaler = experimentalAcceleratedDHTClient(false) func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { d := json.NewDecoder(bytes.NewReader(b)) @@ -462,3 +462,8 @@ func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error { } } } + +// doNotUse is a type you must not use, it should be struct{} but encoding/json +// does not support omitempty on structs and I can't be bothered to write custom +// marshalers on all structs that have a doNotUse field. +type doNotUse bool diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index f891bb570f4..84ebdc0fc40 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -1,6 +1,7 @@ package loader import ( + "encoding/json" "fmt" "io" "os" @@ -9,7 +10,6 @@ import ( "strings" config "github.com/ipfs/kubo/config" - cserialize "github.com/ipfs/kubo/config/serialize" "github.com/ipld/go-ipld-prime/multicodec" "github.com/ipfs/kubo/core" @@ -97,11 +97,10 @@ type PluginLoader struct { func NewPluginLoader(repo string) (*PluginLoader, error) { loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(preloadPlugins)), repo: repo} if repo != "" { - cfg, err := cserialize.Load(filepath.Join(repo, config.DefaultConfigFile)) - switch err { - case cserialize.ErrNotInitialized: - case nil: - loader.config = cfg.Plugins + switch plugins, err := readPluginsConfig(repo, config.DefaultConfigFile); { + case err == nil: + loader.config = plugins + case os.IsNotExist(err): default: return nil, err } @@ -119,6 +118,33 @@ func NewPluginLoader(repo string) (*PluginLoader, error) { return loader, nil } +// readPluginsConfig reads the Plugins section of the IPFS config, avoiding +// reading anything other than the Plugin section. That way, we're free to +// make arbitrary changes to all _other_ sections in migrations. +func readPluginsConfig(repoRoot string, userConfigFile string) (config.Plugins, error) { + var cfg struct { + Plugins config.Plugins + } + + cfgPath, err := config.Filename(repoRoot, userConfigFile) + if err != nil { + return config.Plugins{}, err + } + + cfgFile, err := os.Open(cfgPath) + if err != nil { + return config.Plugins{}, err + } + defer cfgFile.Close() + + err = json.NewDecoder(cfgFile).Decode(&cfg) + if err != nil { + return config.Plugins{}, err + } + + return cfg.Plugins, nil +} + func (loader *PluginLoader) assertState(state loaderState) error { if loader.state != state { return fmt.Errorf("loader state must be %s, was %s", state, loader.state)