summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Lopez <james@jameslopez.es>2016-09-23 09:42:07 +0200
committerJames Lopez <james@jameslopez.es>2016-09-29 15:15:37 +0200
commitcb0202937a44f300f5ddd8da625557e379b9411e (patch)
treeb6b2add029b7529fabfef8197e52fc64603b94f5
parentf6a1a21f6f808738b3caccca1b1233303649f898 (diff)
downloadgitlab-ce-fix/rugged-repo-error.tar.gz
fix broken repo 500 errors in UI and added relevant specsfix/rugged-repo-error
-rw-r--r--CHANGELOG1
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/controllers/projects_controller.rb7
-rw-r--r--app/services/projects/import_service.rb5
-rw-r--r--spec/controllers/projects_controller_spec.rb22
-rw-r--r--spec/factories/projects.rb15
-rw-r--r--spec/services/projects/import_service_spec.rb10
8 files changed, 62 insertions, 4 deletions
diff --git a/CHANGELOG b/CHANGELOG
index e1b9cbf0b1d..d78e1b36160 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@ v 8.13.0 (unreleased)
- Fix resolved discussion display in side-by-side diff view !6575
- Optimize GitHub importing for speed and memory
- API: expose pipeline data in builds API (!6502, Guilherme Salazar)
+ - Fix broken repository 500 errors in project list
v 8.12.2 (unreleased)
- Added University content to doc/university
diff --git a/Gemfile b/Gemfile
index d2677d69556..76ca6427feb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -51,7 +51,7 @@ gem 'browser', '~> 2.2'
# Extracting information from a git repository
# Provide access to Gitlab::Git library
-gem 'gitlab_git', '~> 10.6.6'
+gem 'gitlab_git', '~> 10.6.7'
# LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes
diff --git a/Gemfile.lock b/Gemfile.lock
index 6f6667b51e9..f15715a20ff 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -276,7 +276,7 @@ GEM
diff-lcs (~> 1.1)
mime-types (>= 1.16, < 3)
posix-spawn (~> 0.3)
- gitlab_git (10.6.6)
+ gitlab_git (10.6.7)
activesupport (~> 4.0)
charlock_holmes (~> 0.7.3)
github-linguist (~> 4.7.0)
@@ -857,7 +857,7 @@ DEPENDENCIES
github-linguist (~> 4.7.0)
github-markup (~> 1.4)
gitlab-flowdock-git-hook (~> 1.0.1)
- gitlab_git (~> 10.6.6)
+ gitlab_git (~> 10.6.7)
gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.2)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index eaa38fa6c98..c99aeadb5e4 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -324,7 +324,12 @@ class ProjectsController < Projects::ApplicationController
end
def repo_exists?
- project.repository_exists? && !project.empty_repo?
+ project.repository_exists? && !project.empty_repo? && project.repo
+
+ rescue Gitlab::Git::Repository::NoRepository
+ project.repository.expire_exists_cache
+
+ false
end
def project_view_files?
diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb
index cdad0426b02..e466ffa60eb 100644
--- a/app/services/projects/import_service.rb
+++ b/app/services/projects/import_service.rb
@@ -44,6 +44,11 @@ module Projects
begin
gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url)
rescue => e
+ # Expire cache to prevent scenarios such as:
+ # 1. First import failed, but the repo was imported successfully, so +exists?+ returns true
+ # 2. Retried import, repo is broken or not imported but +exists?+ still returns true
+ project.repository.before_import if project.repository_exists?
+
raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}"
end
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index b0f740f48f7..da0fdce39db 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -63,6 +63,28 @@ describe ProjectsController do
end
end
+ context "project with broken repo" do
+ let(:empty_project) { create(:project_broken_repo, :public) }
+
+ before { sign_in(user) }
+
+ User.project_views.keys.each do |project_view|
+ context "with #{project_view} view set" do
+ before do
+ user.update_attributes(project_view: project_view)
+
+ get :show, namespace_id: empty_project.namespace.path, id: empty_project.path
+ end
+
+ it "renders the empty project view" do
+ allow(Project).to receive(:repo).and_raise(Gitlab::Git::Repository::NoRepository)
+
+ expect(response).to render_template('projects/no_repo')
+ end
+ end
+ end
+ end
+
context "rendering default project view" do
render_views
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index e61b1fd9647..873d3fcb5af 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -27,6 +27,14 @@ FactoryGirl.define do
end
end
+ trait :broken_repo do
+ after(:create) do |project|
+ project.create_repository
+
+ FileUtils.rm_r(File.join(project.repository_storage_path, "#{project.path_with_namespace}.git", 'refs'))
+ end
+ end
+
# Nest Project Feature attributes
transient do
wiki_access_level ProjectFeature::ENABLED
@@ -56,6 +64,13 @@ FactoryGirl.define do
empty_repo
end
+ # Project with broken repository
+ #
+ # Project with an invalid repository state
+ factory :project_broken_repo, parent: :empty_project do
+ broken_repo
+ end
+
# Project with test repository
#
# Test repository source can be found at
diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb
index d5d4d7c56ef..ed1384798ab 100644
--- a/spec/services/projects/import_service_spec.rb
+++ b/spec/services/projects/import_service_spec.rb
@@ -108,6 +108,16 @@ describe Projects::ImportService, services: true do
expect(result[:status]).to eq :error
expect(result[:message]).to eq 'Github: failed to connect API'
end
+
+ it 'expires existence cache after error' do
+ allow_any_instance_of(Project).to receive(:repository_exists?).and_return(true)
+
+ expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).with(project.repository_storage_path, project.path_with_namespace, project.import_url).and_raise(Gitlab::Shell::Error.new('Failed to import the repository'))
+ expect_any_instance_of(Repository).to receive(:expire_emptiness_caches).and_call_original
+ expect_any_instance_of(Repository).to receive(:expire_exists_cache).and_call_original
+
+ subject.execute
+ end
end
def stub_github_omniauth_provider