diff --git a/internal/gitaly/storage/storagemgr/partition/migration/factory.go b/internal/gitaly/storage/storagemgr/partition/migration/factory.go index aa58a705901a815795f45586ccb76737c1e54f2c..d5a26d1cf000cb88a5a50fde2153e9a81a0c3b72 100644 --- a/internal/gitaly/storage/storagemgr/partition/migration/factory.go +++ b/internal/gitaly/storage/storagemgr/partition/migration/factory.go @@ -8,7 +8,9 @@ import ( ) // migrations is a list of configured migrations that must be performed on repositories. -var migrations []migration +var migrations = []migration{ + {1, "info directory removal", taskRemoveInfoFolder, taskRemoveInfoFolderDisabled}, +} // migrationFactory defines a partition factory that wraps another partition factory. type migrationFactory struct { diff --git a/internal/gitaly/storage/storagemgr/partition/migration/manager_test.go b/internal/gitaly/storage/storagemgr/partition/migration/manager_test.go index d983b38423709a7aae93d9b99c57712c49a0fba0..0d0f41e444c840ceb20d704de8a37fa8985829ff 100644 --- a/internal/gitaly/storage/storagemgr/partition/migration/manager_test.go +++ b/internal/gitaly/storage/storagemgr/partition/migration/manager_test.go @@ -30,9 +30,9 @@ func TestMigrationManager_Begin(t *testing.T) { disabledFn := func(context.Context) bool { return true } migrationErr := errors.New("migration error") - errFn := func(context.Context, storage.Transaction) error { return migrationErr } - recordingFn := func(id uint64) func(_ context.Context, txn storage.Transaction) error { - return func(_ context.Context, txn storage.Transaction) error { + errFn := func(context.Context, storage.Transaction, string) error { return migrationErr } + recordingFn := func(id uint64) func(_ context.Context, txn storage.Transaction, _ string) error { + return func(_ context.Context, txn storage.Transaction, _ string) error { return txn.KV().Set(uint64ToBytes(id), nil) } } @@ -131,6 +131,14 @@ func TestMigrationManager_Begin(t *testing.T) { expectedErr: errors.New("repository has invalid migration key: 4"), expectedLastID: 4, }, + { + desc: "info directory removal", + migrations: migrations, + startingMigration: &migration{id: 0}, + expectedState: &migrationState{}, + expectedMigrationIDs: map[uint64]struct{}{1: {}}, + expectedLastID: 1, + }, } { t.Run(tc.desc, func(t *testing.T) { t.Parallel() @@ -249,7 +257,7 @@ func TestMigrationManager_Begin(t *testing.T) { func TestMigrationManager_Concurrent(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - noopFn := func(context.Context, storage.Transaction) error { return nil } + noopFn := func(context.Context, storage.Transaction, string) error { return nil } setupMockPartition := func(firstTransactionFn func(context.Context) error) *mockPartition { kvFn := func() keyvalue.ReadWriter { @@ -423,7 +431,7 @@ func TestMigrationManager_Context(t *testing.T) { }, testhelper.NewLogger(t), NewMetrics(), - []migration{{id: 1, fn: func(ctx context.Context, tx storage.Transaction) error { + []migration{{id: 1, fn: func(ctx context.Context, tx storage.Transaction, _ string) error { // Canceling the context of the request that started this migraiton // should not lead to canceling the migration. requestCancel() diff --git a/internal/gitaly/storage/storagemgr/partition/migration/migration.go b/internal/gitaly/storage/storagemgr/partition/migration/migration.go index 8de7672120e51d072d8a6387b3e836ef62418ba4..27f3c77b20a08a9e594b1459ac501aa7eea57fd5 100644 --- a/internal/gitaly/storage/storagemgr/partition/migration/migration.go +++ b/internal/gitaly/storage/storagemgr/partition/migration/migration.go @@ -5,7 +5,6 @@ import ( "encoding/binary" "errors" "fmt" - "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" ) @@ -22,7 +21,7 @@ type migration struct { // name is a human-readable description for the migration to be used in logs/tracing. name string // fn is the function executed to modify the WAL entry during transaction commit. - fn func(context.Context, storage.Transaction) error + fn func(context.Context, storage.Transaction, string) error // isDisabled defines an optional check to prevent a migration from being executed. isDisabled func(ctx context.Context) bool } @@ -33,7 +32,7 @@ func (m migration) run(ctx context.Context, txn storage.Transaction, relativePat return errInvalidMigration } - if err := m.fn(ctx, txn); err != nil { + if err := m.fn(ctx, txn, relativePath); err != nil { return fmt.Errorf("migrate repository: %w", err) } diff --git a/internal/gitaly/storage/storagemgr/partition/migration/migration_tasks.go b/internal/gitaly/storage/storagemgr/partition/migration/migration_tasks.go new file mode 100644 index 0000000000000000000000000000000000000000..47345fd2864b6498d297d5d6423838fa15e88e4e --- /dev/null +++ b/internal/gitaly/storage/storagemgr/partition/migration/migration_tasks.go @@ -0,0 +1,18 @@ +package migration + +import ( + "context" + "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" + "path/filepath" +) + +// taskRemoveInfoFolder is a migration task that record the removal of git's info directory, (notice is +// not objects/info folder). +func taskRemoveInfoFolder(ctx context.Context, txn storage.Transaction, relativePath string) error { + infoDirRelPath := filepath.Join(relativePath, "info") + return txn.FS().RecordRemoval(infoDirRelPath) +} + +func taskRemoveInfoFolderDisabled(ctx context.Context) bool { + return false +} diff --git a/internal/gitaly/storage/storagemgr/partition/migration/migration_test.go b/internal/gitaly/storage/storagemgr/partition/migration/migration_test.go index 63b4ef2ed7f87e0680d3286068a6f07a8d880d05..551feb93a68bd7ce82a9d7544b74b13f38917a74 100644 --- a/internal/gitaly/storage/storagemgr/partition/migration/migration_test.go +++ b/internal/gitaly/storage/storagemgr/partition/migration/migration_test.go @@ -32,7 +32,7 @@ func TestMigration_Run(t *testing.T) { }, { desc: "migration returns error", - migration: migration{fn: func(context.Context, storage.Transaction) error { + migration: migration{fn: func(context.Context, storage.Transaction, string) error { return migrationErr }}, expectedErr: fmt.Errorf("migrate repository: %w", migrationErr), @@ -41,7 +41,7 @@ func TestMigration_Run(t *testing.T) { desc: "migration modifies transaction", migration: migration{ id: 1, - fn: func(_ context.Context, txn storage.Transaction) error { + fn: func(_ context.Context, txn storage.Transaction, _ string) error { return txn.KV().Set([]byte("foo"), []byte("bar")) }, },