Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Hiltunen <shiltunen@gitlab.com>2023-05-21 12:57:58 +0300
committerSami Hiltunen <shiltunen@gitlab.com>2023-05-25 17:57:47 +0300
commitaa673104814904ac6dc0986a53cfc519466e06e0 (patch)
treeec0f032fdf7dd91616e2c9bb594dbe4c0fedac8e /internal/gitaly/transaction_manager.go
parente9a888be7035afa5d5854110801cdb42b1411e3f (diff)
Validate custom hook archive prior to accepting a transaction
TransactionManager is currently not validating the custom hook archive in any way prior to accepting and logging the transaction. This could lead to invalid hook archive being logged which would prevent applying the log entry of the transaction leading to transaction processing halting. This commit verifies the archive by extracting it on the disk to the staging directory prior to logging. These extracted files can then later be also used for computing a vote to Praefect from the hook files. For now, no other validation is performed than just ensuring the hooks can be extracted on the disk. This matches the behavior in SetCustomHooks which also doesn't verify anything. This is something we should improve later. However, if the hooks extract successfully, the log processing won't fail because of them. If the hooks fail to execute, it will fail the hook execution but that's outside of the scope of the TransactionManager. The hooks can still be fixed by committing new ones.
Diffstat (limited to 'internal/gitaly/transaction_manager.go')
-rw-r--r--internal/gitaly/transaction_manager.go28
1 files changed, 28 insertions, 0 deletions
diff --git a/internal/gitaly/transaction_manager.go b/internal/gitaly/transaction_manager.go
index 5862cd5d2..629ec9da2 100644
--- a/internal/gitaly/transaction_manager.go
+++ b/internal/gitaly/transaction_manager.go
@@ -521,6 +521,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)
}
@@ -544,6 +548,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 {