diff options
author | Konstantin Ryabitsev <konstantin@linuxfoundation.org> | 2019-01-03 11:48:57 -0500 |
---|---|---|
committer | Konstantin Ryabitsev <konstantin@linuxfoundation.org> | 2019-01-03 11:48:57 -0500 |
commit | d23bdf8ea35e8bbc50dd525f6bc27a9c7afe6b18 (patch) | |
tree | 668ce1c1edfea17f41ed692e65ae6baeb8544dde | |
parent | 0cfd11f84c700f56b01c6e125dff6de45ca2d1fe (diff) | |
download | grokmirror-d23bdf8ea35e8bbc50dd525f6bc27a9c7afe6b18.tar.gz |
Set preciousObjects for mother repos
Ensure even manual repacks using "git gc" or "git prune" done by admins
cannot result in repository corruption.
Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
-rw-r--r-- | CHANGELOG.rst | 11 | ||||
-rwxr-xr-x | grokmirror/fsck.py | 36 |
2 files changed, 42 insertions, 5 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f90312c..0bc901a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,6 +20,17 @@ v1.2-master to the git binary using the GITBIN env variable or by simply adding it to your path. +- Add "reclone_on_errors" setting in fsck.conf. If fsck/repack/prune + comes across a matching error, it will mark the repository for + recloning and it will be cloned anew from the master the next time + grok-pull runs. This is useful for auto-correcting corruption on the + mirrors. You can also manually request a reclone by creating a + "grokmirror.reclone" file in a repository. + +- Set extensions.preciousObjects for repositories used with git + alternates. This helps further protect them from erroneous pruning + (e.g. done manually by an administrator). + v1.1.1 (2018-07-25) ------------------- diff --git a/grokmirror/fsck.py b/grokmirror/fsck.py index 95fe623..609f3e3 100755 --- a/grokmirror/fsck.py +++ b/grokmirror/fsck.py @@ -37,15 +37,20 @@ def check_reclone_error(fullpath, config, errors): for line in errors: for estring in config['reclone_on_errors']: if line.find(estring) != -1: - reclone = line - logger.debug('Will re-clone due to this error: %s', line) - logger.info(' error : re-clone requested') + # is preciousObjects set for this repo? + if check_precious_objects(fullpath): + logger.critical('\tpreciousObjects set, not requesting auto-reclone') + return + else: + reclone = line + logger.critical('\trequested auto-reclone') + break + if reclone is not None: break if reclone is None: return - gitdir = '/' + os.path.relpath(fullpath, config['toplevel']).lstrip('/') - rfile = os.path.join(gitdir, 'grokmirror.reclone') + rfile = os.path.join(fullpath, 'grokmirror.reclone') # Have we already requested a reclone? if os.path.exists(rfile): logger.debug('Already requested repo reclone for %s', fullpath) @@ -94,6 +99,7 @@ def run_git_prune(fullpath, config): prune_ok = False for entry in warn: logger.critical("\t%s", entry) + check_reclone_error(fullpath, config, warn) return prune_ok @@ -119,6 +125,7 @@ def run_git_repack(fullpath, config, level=1): gitdir = '/' + os.path.relpath(fullpath, config['toplevel']).lstrip('/') if grokmirror.is_alt_repo(config['toplevel'], gitdir): # we are a "mother repo" + set_precious_objects(fullpath) # are we using alternates ourselves? Multiple levels of alternates are # a bad idea in general due high possibility of corruption. if os.path.exists(os.path.join(fullpath, 'objects', 'info', 'alternates')): @@ -173,6 +180,7 @@ def run_git_repack(fullpath, config, level=1): repack_ok = False for entry in warn: logger.critical("\t%s", entry) + check_reclone_error(fullpath, config, warn) if not repack_ok: # No need to repack refs if repo is broken @@ -216,6 +224,8 @@ def run_git_repack(fullpath, config, level=1): for entry in warn: logger.critical("\t%s", entry) + check_reclone_error(fullpath, config, warn) + if repack_ok and 'prune' in config and config['prune'] == 'yes': # run prune now return run_git_prune(fullpath, config) @@ -255,6 +265,7 @@ def run_git_fsck(fullpath, config, conn_only=False): logger.critical('%s has critical errors:', fullpath) for entry in warn: logger.critical("\t%s", entry) + check_reclone_error(fullpath, config, warn) def get_repo_obj_info(fullpath): @@ -270,6 +281,21 @@ def get_repo_obj_info(fullpath): return obj_info +def set_precious_objects(fullpath): + # It's better to just set it blindly without checking first, + # as this results in one fewer shell-out. + args = ['config', 'extensions.preciousObjects', 'true'] + grokmirror.run_git_command(fullpath, args) + + +def check_precious_objects(fullpath): + args = ['config', '--get', 'extensions.preciousObjects'] + retcode, output, error = grokmirror.run_git_command(fullpath, args) + if output.strip().lower() == 'true': + return True + return False + + def fsck_mirror(name, config, verbose=False, force=False, repack_only=False, conn_only=False, repack_all_quick=False, repack_all_full=False): global logger |