Skip to content

Commit 50fff4b

Browse files
committed
Fixed weird race condition with cron cleanup of /tmp (such as tmpwatch).
Now, clone_or_pull_gitolite_admin() will refuse to merge in existing changes (which could involve deletes from tmpwatch). Instead, it will recognize the unmerged changes and simply delete and reclone. Note that such unmerged changes will not exist unless something bad has happened. Cleanup may require executing a RESYNC_ALL operation (i.e. fetch_changesets).
1 parent 2e23301 commit 50fff4b

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

Diff for: lib/git_hosting.rb

+25-7
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,13 @@ def self.shell(command)
407407
# This routine must only be called after acquisition of the lock
408408
#
409409
# John Kubiatowicz, 11/15/11
410-
def self.clone_or_pull_gitolite_admin
410+
#
411+
# This routine will no-longer merge in changes, since this can cause weird behavior
412+
# when interacting with cron-jobs that clean up /tmp.
413+
#
414+
# John Kubiatowicz, 04/23/12
415+
#
416+
def self.clone_or_pull_gitolite_admin(resync_all_flag)
411417
# clone/pull from admin repo
412418
repo_dir = File.join(get_tmp_dir,GitHosting::GitoliteConfig::ADMIN_REPO)
413419

@@ -421,10 +427,22 @@ def self.clone_or_pull_gitolite_admin
421427
# unmerged changes=> non-empty return
422428
return_val = %x[env GIT_SSH=#{gitolite_ssh()} git --git-dir='#{repo_dir}/.git' --work-tree='#{repo_dir}' status --short].empty?
423429

424-
shell %[chmod 700 "#{repo_dir}" ]
425-
# Make sure we have our hooks setup
426-
GitAdapterHooks.check_hooks_installed
427-
return return_val
430+
if (return_val)
431+
shell %[chmod 700 "#{repo_dir}" ]
432+
# Make sure we have our hooks setup
433+
GitAdapterHooks.check_hooks_installed
434+
return return_val
435+
else
436+
# The attempt to merge can cause a weird failure mode when interacting with cron jobs that clean out old
437+
# files in /tmp. The issue is that keys in the keydir can go idle and get deleted. Then, when we merge we
438+
# create an admin repo minus those keys (including the admin key!). Only a RESYNC_ALL operation will
439+
# actually fix. Thus, we never return "have uncommitted changes", but instead fail the merge and reclone.
440+
#
441+
# 04/23/12
442+
# --KUBI--
443+
logger.error "Seems to be unmerged changes! Going to delete and reclone for safety."
444+
logger.error "May need to execute RESYNC_ALL to fix whatever caused pending changes." unless resync_all_flag
445+
end
428446
rescue
429447
logger.error "Repository fetch and merge failed -- trying to delete and reclone repository."
430448
end
@@ -537,7 +555,7 @@ def self.fixup_gitolite_admin
537555
shell %[#{GitHosting.git_user_runner} "git --git-dir='#{repo_dir}/.git' --work-tree='#{repo_dir}' add conf/gitolite.conf"]
538556
shell %[#{GitHosting.git_user_runner} "git --git-dir='#{repo_dir}/.git' --work-tree='#{repo_dir}' config user.email '#{Setting.mail_from}'"]
539557
shell %[#{GitHosting.git_user_runner} "git --git-dir='#{repo_dir}/.git' --work-tree='#{repo_dir}' config user.name 'Redmine'"]
540-
shell %[#{GitHosting.git_user_runner} "git --git-dir='#{repo_dir}/.git' --work-tree='#{repo_dir}' commit -m 'Emergency repair of gitolite admin key'"]
558+
shell %[#{GitHosting.git_user_runner} "git --git-dir='#{repo_dir}/.git' --work-tree='#{repo_dir}' commit -m 'Updated by Redmine: Emergency repair of gitolite admin key'"]
541559
begin
542560
logger.warn " Pushing fixes using gl-admin-push"
543561
shell %[#{GitHosting.git_user_runner} "cd #{repo_dir}; gl-admin-push -f"]
@@ -670,7 +688,7 @@ def self.update_repositories(*args)
670688
begin
671689
# Make sure we have gitoite-admin cloned.
672690
# If have uncommitted changes, reflect in "changed" flag.
673-
changed = !clone_or_pull_gitolite_admin
691+
changed = !clone_or_pull_gitolite_admin(flags[:resync_all])
674692

675693
# Get directory for the gitolite-admin
676694
repo_dir = File.join(get_tmp_dir,"gitolite-admin")

0 commit comments

Comments
 (0)