fix: correctly handle migration of configs
readPluginsConfig was copied from ReadMigrationConfig and switched erroring fields to a bool so it can be omitemptied.
Jorropo committed
Jun 27, 2023 at 11:15 UTC
f2a6c4f7648e9a60c13ba5b040809e51e72c3266
3 files changed
+42
-11
config/config.go
+1
-1
@@ -83,7 +83,7 @@ func Path(configroot, extension string) (string, error) {
83
// - If the user-provided configuration file path is only a file name, use the
84
// configuration root directory, otherwise use only the user-provided path
85
// and ignore the configuration root.
86
-func Filename(configroot string, userConfigFile string) (string, error) {
86
+func Filename(configroot, userConfigFile string) (string, error) {
87
if userConfigFile == "" {
88
return Path(configroot, DefaultConfigFile)
89
}
config/types.go
+9
-4
@@ -415,9 +415,9 @@ func (p OptionalString) String() string {
415
var _ json.Unmarshaler = (*OptionalInteger)(nil)
416
var _ json.Marshaler = (*OptionalInteger)(nil)
417
418
-type swarmLimits struct{}
418
+type swarmLimits doNotUse
419
420
-var _ json.Unmarshaler = swarmLimits{}
420
+var _ json.Unmarshaler = swarmLimits(false)
421
422
func (swarmLimits) UnmarshalJSON(b []byte) error {
423
d := json.NewDecoder(bytes.NewReader(b))
@@ -439,9 +439,9 @@ func (swarmLimits) UnmarshalJSON(b []byte) error {
439
}
440
}
441
442
-type experimentalAcceleratedDHTClient struct{}
442
+type experimentalAcceleratedDHTClient doNotUse
443
444
-var _ json.Unmarshaler = experimentalAcceleratedDHTClient{}
444
+var _ json.Unmarshaler = experimentalAcceleratedDHTClient(false)
445
446
func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error {
447
d := json.NewDecoder(bytes.NewReader(b))
@@ -462,3 +462,8 @@ func (experimentalAcceleratedDHTClient) UnmarshalJSON(b []byte) error {
462
}
463
}
464
}
465
+
466
+// doNotUse is a type you must not use, it should be struct{} but encoding/json
467
+// does not support omitempty on structs and I can't be bothered to write custom
468
+// marshalers on all structs that have a doNotUse field.
469
+type doNotUse bool
plugin/loader/loader.go
+32
-6
@@ -1,6 +1,7 @@
1
package loader
2
3
import (
4
+ "encoding/json"
5
"fmt"
6
"io"
7
"os"
@@ -9,7 +10,6 @@ import (
10
"strings"
11
12
config "github.com/ipfs/kubo/config"
12
- cserialize "github.com/ipfs/kubo/config/serialize"
13
"github.com/ipld/go-ipld-prime/multicodec"
14
15
"github.com/ipfs/kubo/core"
@@ -97,11 +97,10 @@ type PluginLoader struct {
97
func NewPluginLoader(repo string) (*PluginLoader, error) {
98
loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(preloadPlugins)), repo: repo}
99
if repo != "" {
100
- cfg, err := cserialize.Load(filepath.Join(repo, config.DefaultConfigFile))
101
- switch err {
102
- case cserialize.ErrNotInitialized:
103
- case nil:
104
- loader.config = cfg.Plugins
100
+ switch plugins, err := readPluginsConfig(repo, config.DefaultConfigFile); {
101
+ case err == nil:
102
+ loader.config = plugins
103
+ case os.IsNotExist(err):
104
default:
105
return nil, err
106
}
@@ -119,6 +118,33 @@ func NewPluginLoader(repo string) (*PluginLoader, error) {
118
return loader, nil
119
}
120
121
+// readPluginsConfig reads the Plugins section of the IPFS config, avoiding
122
+// reading anything other than the Plugin section. That way, we're free to
123
+// make arbitrary changes to all _other_ sections in migrations.
124
+func readPluginsConfig(repoRoot string, userConfigFile string) (config.Plugins, error) {
125
+ var cfg struct {
126
+ Plugins config.Plugins
127
+ }
128
+
129
+ cfgPath, err := config.Filename(repoRoot, userConfigFile)
130
+ if err != nil {
131
+ return config.Plugins{}, err
132
+ }
133
+
134
+ cfgFile, err := os.Open(cfgPath)
135
+ if err != nil {
136
+ return config.Plugins{}, err
137
+ }
138
+ defer cfgFile.Close()
139
+
140
+ err = json.NewDecoder(cfgFile).Decode(&cfg)
141
+ if err != nil {
142
+ return config.Plugins{}, err
143
+ }
144
+
145
+ return cfg.Plugins, nil
146
+}
147
+
148
func (loader *PluginLoader) assertState(state loaderState) error {
149
if loader.state != state {
150
return fmt.Errorf("loader state must be %s, was %s", state, loader.state)