summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2018-08-22 10:43:15 -0700
committerStan Hu <stanhu@gmail.com>2018-08-22 10:43:15 -0700
commitb8662c2796f03449502adeecd23027b98ec62b63 (patch)
tree0d420201cfde712137ff7da1619b1a50b0ff29a2
parentf1315c85f91c76d308069a741db2a4a0d89d509e (diff)
downloadgitlab-ce-sh-ensure-remote-exists.tar.gz
Ensure remote exists for a remote mirror before attempting to fetchsh-ensure-remote-exists
Closes #50562
-rw-r--r--app/models/remote_mirror.rb7
-rw-r--r--app/services/projects/update_remote_mirror_service.rb1
-rw-r--r--lib/gitlab/git/repository.rb7
-rw-r--r--lib/gitlab/gitaly_client/remote_service.rb16
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb27
5 files changed, 58 insertions, 0 deletions
diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb
index 833faf3bc82..19d38e9e962 100644
--- a/app/models/remote_mirror.rb
+++ b/app/models/remote_mirror.rb
@@ -195,6 +195,13 @@ class RemoteMirror < ActiveRecord::Base
self.remote_name = "remote_mirror_#{SecureRandom.hex}"
end
+ def ensure_remote!
+ return unless project
+ return unless remote_name && url
+
+ project.repository.add_remote(remote_name, url) unless project.repository.remote_exists?(remote_name)
+ end
+
def refresh_remote
return unless project
diff --git a/app/services/projects/update_remote_mirror_service.rb b/app/services/projects/update_remote_mirror_service.rb
index 4651f7c4f8f..591b38b8151 100644
--- a/app/services/projects/update_remote_mirror_service.rb
+++ b/app/services/projects/update_remote_mirror_service.rb
@@ -10,6 +10,7 @@ module Projects
return success unless remote_mirror.enabled?
begin
+ remote_mirror.ensure_remote!
repository.fetch_remote(remote_mirror.remote_name, no_tags: true)
opts = {}
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 9521a2d63a0..0ca04a3765f 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -666,6 +666,13 @@ module Gitlab
end
end
+ # This can be a remote name or URL per `man git-ls-remote`
+ def remote_exists?(remote_name)
+ wrapped_gitaly_errors do
+ gitaly_remote_client.remote_exists?(remote_name)
+ end
+ end
+
AUTOCRLF_VALUES = {
"true" => true,
"false" => false,
diff --git a/lib/gitlab/gitaly_client/remote_service.rb b/lib/gitlab/gitaly_client/remote_service.rb
index 1381e033d4b..c70a7c9d53e 100644
--- a/lib/gitlab/gitaly_client/remote_service.rb
+++ b/lib/gitlab/gitaly_client/remote_service.rb
@@ -3,6 +3,8 @@ module Gitlab
class RemoteService
MAX_MSG_SIZE = 128.kilobytes.freeze
+ # This checks whether a remote URL exists (e.g. for imports). Not to
+ # be confused with remote_exists? below.
def self.exists?(remote_url)
request = Gitaly::FindRemoteRepositoryRequest.new(remote: remote_url)
@@ -39,6 +41,20 @@ module Gitlab
response.result
end
+ def remote_exists?(name)
+ request = Gitaly::RemoteExistsRequest.new(
+ repository: @gitaly_repo,
+ name_or_url: name
+ )
+
+ response = GitalyClient.call(@storage,
+ :remote_service,
+ :remote_exists, request,
+ timeout: GitalyClient.fast_timeout)
+
+ response.exists
+ end
+
def fetch_internal_remote(repository)
request = Gitaly::FetchInternalRemoteRequest.new(
repository: @gitaly_repo,
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 17348b01006..760d85aceb8 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -1901,6 +1901,33 @@ describe Gitlab::Git::Repository, :seed_helper do
it_behaves_like 'remove_remote'
end
end
+
+ describe '#remote_exists?' do
+ shared_examples 'remote_exists?' do
+ it 'detects existence with a remote name or URL' do
+ expect(repository.remote_exists?(remote_name)).to be_falsey
+ expect(repository.remote_exists?(url)).to be_falsey
+
+ repository.add_remote(remote_name, url)
+
+ expect(repository.remote_exists?(remote_name)).to be_truthy
+ expect(repository.remote_exists?(url)).to be_truthy
+
+ repository.remove_remote(remote_name)
+
+ expect(repository.remote_exists?(remote_name)).to be_falsey
+ expect(repository.remote_exists?(url)).to be_falsey
+ end
+ end
+
+ context 'using Gitaly' do
+ it_behaves_like 'remote_exists?'
+ end
+
+ context 'with Gitaly disabled', :disable_gitaly do
+ it_behaves_like 'remote_exists?'
+ end
+ end
end
describe '#gitlab_projects' do