diff options
author | Justin Tobler <jtobler@gitlab.com> | 2023-05-30 20:44:55 +0300 |
---|---|---|
committer | Justin Tobler <jtobler@gitlab.com> | 2023-05-30 20:44:55 +0300 |
commit | 689207391584ced7381371aaa29f299c436edac2 (patch) | |
tree | 4bbc7f0fee7b2d549ea4fc4ac54bdbc1223d567f /internal/gitaly/transaction_manager.go | |
parent | f02566b02ce1b1ffecb7046eecd533f5191da45a (diff) | |
parent | aa673104814904ac6dc0986a53cfc519466e06e0 (diff) |
Merge branch 'smh-validate-hooks' into 'master'
Validate custom hook archive prior to accepting a transaction
Closes #5126
See merge request https://gitlab.com/gitlab-org/gitaly/-/merge_requests/5835
Merged-by: Justin Tobler <jtobler@gitlab.com>
Approved-by: Justin Tobler <jtobler@gitlab.com>
Approved-by: Toon Claes <toon@gitlab.com>
Co-authored-by: Sami Hiltunen <shiltunen@gitlab.com>
Diffstat (limited to 'internal/gitaly/transaction_manager.go')
-rw-r--r-- | internal/gitaly/transaction_manager.go | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/internal/gitaly/transaction_manager.go b/internal/gitaly/transaction_manager.go index 82f2d6983..fd1b71284 100644 --- a/internal/gitaly/transaction_manager.go +++ b/internal/gitaly/transaction_manager.go @@ -188,10 +188,6 @@ func (mgr *TransactionManager) Begin(ctx context.Context) (_ *Transaction, retur } mgr.mutex.Lock() - if !mgr.repositoryExists { - mgr.mutex.Unlock() - return nil, ErrRepositoryNotFound - } txn := &Transaction{ commit: mgr.commit, @@ -213,6 +209,7 @@ func (mgr *TransactionManager) Begin(ctx context.Context) (_ *Transaction, retur openTransactionElement := mgr.openTransactions.PushBack(txn) readReady := mgr.applyNotifications[txn.snapshot.ReadIndex] + repositoryExists := mgr.repositoryExists mgr.mutex.Unlock() if readReady == nil { // The snapshot log entry is already applied if there is no notification channel for it. @@ -261,6 +258,10 @@ func (mgr *TransactionManager) Begin(ctx context.Context) (_ *Transaction, retur case <-mgr.ctx.Done(): return nil, ErrTransactionProcessingStopped case <-readReady: + if !repositoryExists { + return nil, ErrRepositoryNotFound + } + return txn, nil } } @@ -513,6 +514,10 @@ func (mgr *TransactionManager) commit(ctx context.Context, transaction *Transact return fmt.Errorf("setup staging repository: %w", err) } + if err := mgr.stageHooks(ctx, transaction); err != nil { + return fmt.Errorf("stage hooks: %w", err) + } + if err := mgr.packObjects(ctx, transaction); err != nil { return fmt.Errorf("pack objects: %w", err) } @@ -536,6 +541,30 @@ func (mgr *TransactionManager) commit(ctx context.Context, transaction *Transact } } +// stageHooks extracts the new hooks, if any, into <stagingDirectory>/custom_hooks. This is ensures the TAR +// is valid prior to committing the transaction. The hooks files on the disk are also used to compute a vote +// for Praefect. +func (mgr *TransactionManager) stageHooks(ctx context.Context, transaction *Transaction) error { + if transaction.customHooksUpdate == nil || len(transaction.customHooksUpdate.CustomHooksTAR) == 0 { + return nil + } + + if err := transaction.initStagingDirectory(); err != nil { + return fmt.Errorf("init staging directory: %w", err) + } + + if err := repoutil.ExtractHooks( + ctx, + bytes.NewReader(transaction.customHooksUpdate.CustomHooksTAR), + transaction.stagingDirectory, + false, + ); err != nil { + return fmt.Errorf("extract hooks: %w", err) + } + + return nil +} + // setupStagingRepository sets a repository that is used to stage the transaction. The staging repository // has the quarantine applied so the objects are available for packing and verifying the references. func (mgr *TransactionManager) setupStagingRepository(ctx context.Context, transaction *Transaction) error { |