Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- from interruptingcow import timeout as interruptingcow_timeout
- class MigrationAbortException(Exception):
- """Exception raised when a migration is aborted."""
- pass
- def lock_repository_ref_updates(repo_path: bytes):
- """git never updates refs or packed-refs file in-place. It always writes into a
- new temporary file and renames. Making the parent directory read-only is sufficient
- to prevent creating temporary file or renaming the file since there are directory updates"""
- migration_abort_sentinel = os.path.join(repo_path, b'migration-abort-sentinel')
- refs_dir = os.path.join(repo_path, b'refs')
- def make_dir_read_only(path: bytes):
- # Even if we are in uninterruptible state, SIGALRM will eventually
- # get delivered to the process. Once delivered, will raise exception
- with interruptingcow_timeout(seconds=60, exception=MigrationAbortException):
- try:
- os.chmod(path, 0o500)
- except FileNotFoundError:
- pass
- except Exception as ex:
- raise MigrationAbortException(ex)
- # Check if rollback is initiated and bailout
- if os.access(migration_abort_sentinel, os.R_OK):
- raise MigrationAbortException()
- # Lock top-down and this will ensure the level
- # we are iterating will not change beneath us
- make_dir_read_only(refs_dir)
- for root, dirs, _ in os.walk(top=refs_dir, topdown=False):
- for name in dirs:
- make_dir_read_only(path=os.path.join(root, name))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement