diff --git a/fs-repo-12-to-13/migration/config.go b/fs-repo-12-to-13/migration/config.go new file mode 100644 index 00000000..1233e136 --- /dev/null +++ b/fs-repo-12-to-13/migration/config.go @@ -0,0 +1,110 @@ +package mg12 + +import ( + log "github.com/ipfs/fs-repo-migrations/tools/stump" +) + +// convertRouting converts Routing.Type to implicit default +// https://github.com/ipfs/kubo/pull/9475 +func convertRouting(confMap map[string]any) { + routing, _ := confMap["Routing"].(map[string]any) + if routing == nil { + log.Log("No Routing field in config, skipping") + return + } + + rType, ok := routing["Type"].(string) + if !ok { + log.Log("No Routing.Type field in config, skipping") + return + } + if rType == "dht" || rType == "" { + delete(routing, "Type") + } else { + log.Log("Routing.Type settings is different than the old default, skipping") + } +} + +// convertReprovider converts Reprovider to implicit defaults +// https://github.com/ipfs/kubo/pull/9326 +func convertReprovider(confMap map[string]any) { + reprovider, _ := confMap["Reprovider"].(map[string]any) + if reprovider == nil { + log.Log("No Reprovider field in config, skipping") + return + } + + interval, ok := reprovider["Interval"].(string) + if !ok { + log.Log("No Reprovider.Interval field in config, skipping") + return + } + if interval == "12h" { + delete(reprovider, "Interval") + } else { + log.Log("Reprovider.Interval settings is different than the old default, skipping") + } + + strategy, ok := reprovider["Strategy"].(string) + if !ok { + log.Log("No Reprovider.Strategy field in config, skipping") + return + } + if strategy == "all" { + delete(reprovider, "Strategy") + } else { + log.Log("Reprovider.Strategy settings is different than the old default, skipping") + } +} + +// convertConnMgr converts Swarm.ConnMgr to implicit defaults +// https://github.com/ipfs/kubo/pull/9467 +func convertConnMgr(confMap map[string]any) { + swarm, _ := confMap["Swarm"].(map[string]any) + if swarm == nil { + log.Log("No Swarm field in config, skipping") + return + } + connmgr, _ := swarm["ConnMgr"].(map[string]any) + if connmgr == nil { + log.Log("No Swarm.ConnMgr field in config, skipping") + return + } + cmType, ok := connmgr["Type"].(string) + if !ok { + log.Log("No Swarm.ConnMgr.Type field in config, skipping") + return + } + cmLowWater, ok := connmgr["LowWater"].(float64) + if !ok { + log.Log("No Swarm.ConnMgr.LowWater field in config, skipping") + return + } + cmHighWater, ok := connmgr["HighWater"].(float64) + if !ok { + log.Log("No Swarm.ConnMgr.HighWater field in config, skipping") + return + } + cmGrace, ok := connmgr["GracePeriod"].(string) + if !ok { + log.Log("No Swarm.ConnMgr.GracePeriod field in config, skipping") + return + } + + if cmType == "basic" { + delete(connmgr, "Type") + if cmGrace == "20s" { + delete(connmgr, "GracePeriod") + } else { + log.Log("Swarm.ConnMgr.GracePeriod setting are different than the old defaults, skipping") + } + if int(cmLowWater) == 600 && int(cmHighWater) == 900 { + delete(connmgr, "LowWater") + delete(connmgr, "HighWater") + } else { + log.Log("Swarm.ConnMgr Low/HighWater settings are different than the old defaults, skipping") + } + } else { + log.Log("Swarm.ConnMgr settings are different than the old defaults, skipping") + } +} diff --git a/fs-repo-12-to-13/migration/config_test.go b/fs-repo-12-to-13/migration/config_test.go new file mode 100644 index 00000000..3d63253e --- /dev/null +++ b/fs-repo-12-to-13/migration/config_test.go @@ -0,0 +1,84 @@ +package mg12 + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "regexp" + "strings" + "testing" +) + +var beforeConfig = `{ + "Reprovider": { + "Interval": "12h", + "Strategy": "all" + }, + "Routing": { + "Methods": {}, + "Routers": {}, + "Type": "dht" + }, + "Swarm": { + "ConnMgr": { + "GracePeriod": "20s", + "HighWater": 900, + "LowWater": 600, + "Type": "basic" + } + } +}` + +var afterConfig = `{ + "Reprovider": {}, + "Routing": { + "Methods": {}, + "Routers": {} + }, + "Swarm": { + "ConnMgr": {} + } +}` + +func TestKubo18ConfigMigration(t *testing.T) { + out := new(bytes.Buffer) + + data, err := ioutil.ReadAll(strings.NewReader(beforeConfig)) + if err != nil { + t.Fatal(err) + } + + confMap := make(map[string]interface{}) + if err = json.Unmarshal(data, &confMap); err != nil { + t.Fatal(err) + } + + // Kubo 0.18 + convertRouting(confMap) + convertReprovider(confMap) + convertConnMgr(confMap) + + fixed, err := json.MarshalIndent(confMap, "", " ") + if err != nil { + t.Fatal(err) + } + + if _, err := out.Write(fixed); err != nil { + t.Fatal(err) + } + _, err = out.Write([]byte("\n")) + if err != nil { + t.Fatal(err) + } + + forward := out.String() + if noSpace(forward) != noSpace(afterConfig) { + t.Fatalf("Mismatch\nConversion produced:\n%s\nExpected:\n%s\n", forward, afterConfig) + } +} + +var whitespaceRe = regexp.MustCompile(`\s`) + +func noSpace(str string) string { + return whitespaceRe.ReplaceAllString(str, "") +} diff --git a/fs-repo-12-to-13/migration/migration.go b/fs-repo-12-to-13/migration/migration.go index 95e24a91..99da4dd3 100644 --- a/fs-repo-12-to-13/migration/migration.go +++ b/fs-repo-12-to-13/migration/migration.go @@ -1,5 +1,6 @@ // package mg12 contains the code to perform 12-13 repository migration in Kubo. -// This just change some config fields to add webtransport listens on ones that quic uses. +// This just change some config fields to add webtransport listens on ones that quic uses, +// and removes some hardcoded defaults that are no longer present on fresh 'ipfs init'. package mg12 import ( @@ -27,7 +28,7 @@ func (m Migration) Versions() string { return "12-to-13" } -// Reversible returns false, as you can just use the backup config file. +// Reversible returns true, as we keep old config around func (m Migration) Reversible() bool { return true } @@ -156,6 +157,10 @@ func convert(in io.Reader, out io.Writer) error { runOnAllAddressFields(confMap, multiaddrPatternReplace(true, "/quic", "/quic-v1", "/p2p-circuit")) runOnAllAddressFields(confMap, multiaddrPatternReplace(true, "/quic-v1", "/quic-v1/webtransport", "/p2p-circuit", "/webtransport")) + convertRouting(confMap) + convertReprovider(confMap) + convertConnMgr(confMap) + fixed, err := json.MarshalIndent(confMap, "", " ") if err != nil { return err