github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/kv/migration.go (about)

     1  package kv
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/treeverse/lakefs/pkg/kv/kvparams"
     9  	"github.com/treeverse/lakefs/pkg/logging"
    10  )
    11  
    12  type Migrator interface {
    13  	Migrate(ctx context.Context) error
    14  }
    15  
    16  type DatabaseMigrator struct {
    17  	params kvparams.Config
    18  }
    19  
    20  var (
    21  	ErrMigrationVersion  = errors.New("wrong kv version")
    22  	ErrMigrationRequired = errors.New("migration required")
    23  )
    24  
    25  func NewDatabaseMigrator(params kvparams.Config) *DatabaseMigrator {
    26  	return &DatabaseMigrator{
    27  		params: params,
    28  	}
    29  }
    30  
    31  func (d *DatabaseMigrator) Migrate(ctx context.Context) error {
    32  	kvStore, err := Open(ctx, d.params)
    33  	if err != nil {
    34  		return fmt.Errorf("failed to open KV store: %w", err)
    35  	}
    36  	defer kvStore.Close()
    37  	version, err := GetDBSchemaVersion(ctx, kvStore)
    38  	if err != nil && !errors.Is(err, ErrNotFound) {
    39  		return fmt.Errorf("failed to setup KV store: %w", err)
    40  	}
    41  	if version < InitialMigrateVersion { // 0 In case of ErrNotFound
    42  		return SetDBSchemaVersion(ctx, kvStore, NextSchemaVersion-1)
    43  	}
    44  	return nil
    45  }
    46  
    47  func ValidateSchemaVersion(ctx context.Context, store Store) (int, error) {
    48  	kvVersion, err := GetDBSchemaVersion(ctx, store)
    49  	if errors.Is(err, ErrNotFound) {
    50  		// probably a new installation
    51  		return 0, ErrNotFound
    52  	}
    53  	if err != nil {
    54  		return 0, fmt.Errorf("get KV schema version: %w", err)
    55  	}
    56  	switch {
    57  	case kvVersion >= NextSchemaVersion:
    58  		return kvVersion, fmt.Errorf("incompatible schema version. Latest: %d: %w", NextSchemaVersion-1, ErrMigrationVersion)
    59  	case kvVersion < InitialMigrateVersion:
    60  		return kvVersion, fmt.Errorf("migration to KV required. Did you migrate using version v0.80.x? https://docs.lakefs.io/reference/upgrade.html#lakefs-0800-or-greater-kv-migration: %w", ErrMigrationVersion)
    61  	case kvVersion < ACLMigrateVersion,
    62  		kvVersion < ACLNoReposMigrateVersion:
    63  		return kvVersion, fmt.Errorf("migration to ACL required. Please run 'lakefs migrate up': %w", ErrMigrationRequired)
    64  	case kvVersion < ACLImportMigrateVersion:
    65  		return kvVersion, fmt.Errorf("ACL migration required. Please run 'lakefs migrate up': %w", ErrMigrationRequired)
    66  	}
    67  
    68  	logging.FromContext(ctx).WithField("version", kvVersion).Info("KV valid")
    69  	return kvVersion, nil
    70  }