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 }