kubo/repo/fsrepo/migrations/fs-repo-17-to-18/migration/migration.go
Marcin Rataj 71e883440e
Some checks are pending
CodeQL / codeql (push) Waiting to run
Docker Check / lint (push) Waiting to run
Docker Check / build (push) Waiting to run
Gateway Conformance / gateway-conformance (push) Waiting to run
Gateway Conformance / gateway-conformance-libp2p-experiment (push) Waiting to run
Go Build / go-build (push) Waiting to run
Go Check / go-check (push) Waiting to run
Go Lint / go-lint (push) Waiting to run
Go Test / go-test (push) Waiting to run
Interop / interop-prep (push) Waiting to run
Interop / helia-interop (push) Blocked by required conditions
Interop / ipfs-webui (push) Blocked by required conditions
Sharness / sharness-test (push) Waiting to run
Spell Check / spellcheck (push) Waiting to run
refactor(config): migration 17-to-18 to unify Provider/Reprovider into Provide.DHT (#10951)
* refactor: consolidate Provider/Reprovider into unified Provide config

- merge Provider and Reprovider configs into single Provide section
- add fs-repo-17-to-18 migration for config consolidation
- improve migration ergonomics with common package utilities
- convert deprecated "flat" strategy to "all" during migration
- improve Provide docs

* docs: add total_provide_count metric guidance

- document how to monitor provide success rates via prometheus metrics
- add performance comparison section to changelog
- explain how to evaluate sweep vs legacy provider effectiveness

* fix: add OpenTelemetry meter provider for metrics

- set up meter provider with Prometheus exporter in daemon
- enables metrics from external libs like go-libp2p-kad-dht
- fixes missing total_provide_count_total when SweepEnabled=true
- update docs to reflect actual metric names

---------

Co-authored-by: gammazero <11790789+gammazero@users.noreply.github.com>
Co-authored-by: guillaumemichel <guillaume@michel.id>
Co-authored-by: Daniel Norman <1992255+2color@users.noreply.github.com>
Co-authored-by: Hector Sanjuan <code@hector.link>
2025-09-18 22:17:43 +02:00

122 lines
4.2 KiB
Go

// package mg17 contains the code to perform 17-18 repository migration in Kubo.
// This handles the following:
// - Migrate Provider and Reprovider configs to unified Provide config
// - Clear deprecated Provider and Reprovider fields
// - Increment repo version to 18
package mg17
import (
"fmt"
"io"
"github.com/ipfs/kubo/repo/fsrepo/migrations/common"
)
// Migration is the main exported migration for 17-to-18
var Migration = &common.BaseMigration{
FromVersion: "17",
ToVersion: "18",
Description: "Migrating Provider and Reprovider configuration to unified Provide configuration",
Convert: convert,
}
// NewMigration creates a new migration instance (for compatibility)
func NewMigration() common.Migration {
return Migration
}
// convert performs the actual configuration transformation
func convert(in io.ReadSeeker, out io.Writer) error {
// Read the configuration
confMap, err := common.ReadConfig(in)
if err != nil {
return err
}
// Create new Provide section with DHT subsection from Provider and Reprovider
provide := make(map[string]any)
dht := make(map[string]any)
hasNonDefaultValues := false
// Migrate Provider fields if they exist
provider := common.SafeCastMap(confMap["Provider"])
if enabled, exists := provider["Enabled"]; exists {
provide["Enabled"] = enabled
// Log migration for non-default values
if enabledBool, ok := enabled.(bool); ok && !enabledBool {
fmt.Printf(" Migrated Provider.Enabled=%v to Provide.Enabled=%v\n", enabledBool, enabledBool)
hasNonDefaultValues = true
}
}
if workerCount, exists := provider["WorkerCount"]; exists {
dht["MaxWorkers"] = workerCount
// Log migration for all worker count values
if count, ok := workerCount.(float64); ok {
fmt.Printf(" Migrated Provider.WorkerCount=%v to Provide.DHT.MaxWorkers=%v\n", int(count), int(count))
hasNonDefaultValues = true
// Additional guidance for high WorkerCount
if count > 5 {
fmt.Printf(" ⚠️ For better resource utilization, consider enabling Provide.DHT.SweepEnabled=true\n")
fmt.Printf(" and adjusting Provide.DHT.DedicatedBurstWorkers if announcement of new CIDs\n")
fmt.Printf(" should take priority over periodic reprovide interval.\n")
}
}
}
// Note: Skip Provider.Strategy as it was unused
// Migrate Reprovider fields if they exist
reprovider := common.SafeCastMap(confMap["Reprovider"])
if strategy, exists := reprovider["Strategy"]; exists {
if strategyStr, ok := strategy.(string); ok {
// Convert deprecated "flat" strategy to "all"
if strategyStr == "flat" {
provide["Strategy"] = "all"
fmt.Printf(" Migrated deprecated Reprovider.Strategy=\"flat\" to Provide.Strategy=\"all\"\n")
} else {
// Migrate any other strategy value as-is
provide["Strategy"] = strategyStr
fmt.Printf(" Migrated Reprovider.Strategy=\"%s\" to Provide.Strategy=\"%s\"\n", strategyStr, strategyStr)
}
hasNonDefaultValues = true
} else {
// Not a string, set to default "all" to ensure valid config
provide["Strategy"] = "all"
fmt.Printf(" Warning: Reprovider.Strategy was not a string, setting Provide.Strategy=\"all\"\n")
hasNonDefaultValues = true
}
}
if interval, exists := reprovider["Interval"]; exists {
dht["Interval"] = interval
// Log migration for non-default intervals
if intervalStr, ok := interval.(string); ok && intervalStr != "22h" && intervalStr != "" {
fmt.Printf(" Migrated Reprovider.Interval=\"%s\" to Provide.DHT.Interval=\"%s\"\n", intervalStr, intervalStr)
hasNonDefaultValues = true
}
}
// Note: Sweep is a new field introduced in v0.38, not present in v0.37
// So we don't need to migrate it from Reprovider
// Set the DHT section if we have any DHT fields to migrate
if len(dht) > 0 {
provide["DHT"] = dht
}
// Set the new Provide section if we have any fields to migrate
if len(provide) > 0 {
confMap["Provide"] = provide
}
// Clear old Provider and Reprovider sections
delete(confMap, "Provider")
delete(confMap, "Reprovider")
// Print documentation link if we migrated any non-default values
if hasNonDefaultValues {
fmt.Printf(" See: https://github.com/ipfs/kubo/blob/master/docs/config.md#provide\n")
}
// Write the updated config
return common.WriteConfig(out, confMap)
}