code.vegaprotocol.io/vega@v0.79.0/datanode/networkhistory/ipfs/migration.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package ipfs
    17  
    18  import (
    19  	"fmt"
    20  
    21  	"code.vegaprotocol.io/vega/logging"
    22  
    23  	mg12 "github.com/ipfs/fs-repo-migrations/fs-repo-12-to-13/migration"
    24  	mg13 "github.com/ipfs/fs-repo-migrations/fs-repo-13-to-14/migration"
    25  	mg14 "github.com/ipfs/fs-repo-migrations/fs-repo-14-to-15/migration"
    26  	migrate "github.com/ipfs/fs-repo-migrations/tools/go-migrate"
    27  	"github.com/ipfs/kubo/repo/fsrepo"
    28  	"github.com/ipfs/kubo/repo/fsrepo/migrations"
    29  )
    30  
    31  // LatestSupportedVersion returns the latest version supported by the kubo library.
    32  func latestSupportedVersion() int {
    33  	// TODO: Maybe We should hardcode it to be safe and control when the migration happens?
    34  	return fsrepo.RepoVersion
    35  }
    36  
    37  // MigrateIpfsStorageVersion migrates the IPFS store to the latest supported by the
    38  // library version.
    39  func MigrateIpfsStorageVersion(log *logging.Logger, ipfsDir string) error {
    40  	repoVersion, err := migrations.RepoVersion(ipfsDir)
    41  	if err != nil {
    42  		return fmt.Errorf("failed to check version for the %s IPFS repository: %w", ipfsDir, err)
    43  	}
    44  
    45  	// migration not needed
    46  	if repoVersion >= latestSupportedVersion() {
    47  		if log != nil {
    48  			log.Info("The IPFS for the network-history is up to date. Migration not needed")
    49  		}
    50  
    51  		return nil
    52  	}
    53  
    54  	localIpfsDir, err := migrations.IpfsDir(ipfsDir)
    55  	if err != nil {
    56  		return fmt.Errorf("failed to find local ipfs directory: %w", err)
    57  	}
    58  
    59  	if err := runMigrations(repoVersion, localIpfsDir); err != nil {
    60  		return fmt.Errorf("failed to execute the ipfs migration: %w", err)
    61  	}
    62  
    63  	return nil
    64  }
    65  
    66  func runMigrations(currentVersion int, ipfsDir string) error {
    67  	migrationsSteps, err := requiredMigrations(currentVersion)
    68  	if err != nil {
    69  		return fmt.Errorf("failed to determine required migrations: %w", err)
    70  	}
    71  
    72  	for _, m := range migrationsSteps {
    73  		if err := m.Apply(migrate.Options{
    74  			Flags: migrate.Flags{
    75  				// Force: true,
    76  				Revert:   false,
    77  				Path:     ipfsDir,
    78  				Verbose:  true,
    79  				NoRevert: true,
    80  			},
    81  			Verbose: true,
    82  		}); err != nil {
    83  			return fmt.Errorf("failed to run migration for %s: %w", m.Versions(), err)
    84  		}
    85  	}
    86  
    87  	return nil
    88  }
    89  
    90  func requiredMigrations(currentVersion int) ([]migrate.Migration, error) {
    91  	availableMigrations := []migrate.Migration{
    92  		// We do not care about older versions. We are migrating repository
    93  		// for vega 0.73. `Vega@v0.73` has `kubo@v0.20.0` which should contain
    94  		// repository v13 (as per https://github.com/ipfs/fs-repo-migrations/tree/master?tab=readme-ov-file#when-should-i-migrate).
    95  		// Older versions depends on ancient versions of packages that causes
    96  		// issue for go 1.21...
    97  		nil,               // 0-1
    98  		nil,               // 1-2
    99  		nil,               // 2-3
   100  		nil,               // 3-4
   101  		nil,               // 4-5
   102  		nil,               // 5-6
   103  		nil,               // 6-7
   104  		nil,               // 7-8
   105  		nil,               // 8-9
   106  		nil,               // 9-10
   107  		nil,               // 10-11
   108  		nil,               // 11-12
   109  		&mg12.Migration{}, // 12-13
   110  		&mg13.Migration{}, // 13-14
   111  		&mg14.Migration{}, // 14-15
   112  	}
   113  
   114  	requiredMigrations := []migrate.Migration{}
   115  
   116  	// no migration required
   117  	if currentVersion >= len(availableMigrations) {
   118  		return requiredMigrations, nil
   119  	}
   120  
   121  	for fromVersion := currentVersion; fromVersion < len(availableMigrations); fromVersion++ {
   122  		if availableMigrations[fromVersion] == nil {
   123  			return nil, fmt.Errorf("migration from version %d is not supported: minimum supported version to migrate the ipfs repo from is 13", fromVersion)
   124  		}
   125  		requiredMigrations = append(requiredMigrations, availableMigrations[fromVersion])
   126  	}
   127  
   128  	return requiredMigrations, nil
   129  }