Commit 885a4da2 authored by Alejandro Rodríguez's avatar Alejandro Rodríguez

Add feature flag to use gitaly-ssh mirroring when cloning internal repos

This also allows us to simplify the naming since we can make some
fetching methods private.
parent d87d1e79
...@@ -20,6 +20,7 @@ module Gitlab ...@@ -20,6 +20,7 @@ module Gitlab
SEARCH_CONTEXT_LINES = 3 SEARCH_CONTEXT_LINES = 3
REBASE_WORKTREE_PREFIX = 'rebase'.freeze REBASE_WORKTREE_PREFIX = 'rebase'.freeze
SQUASH_WORKTREE_PREFIX = 'squash'.freeze SQUASH_WORKTREE_PREFIX = 'squash'.freeze
GITALY_INTERNAL_URL = 'ssh://gitaly/internal.git'.freeze
NoRepository = Class.new(StandardError) NoRepository = Class.new(StandardError)
InvalidBlobName = Class.new(StandardError) InvalidBlobName = Class.new(StandardError)
...@@ -1140,12 +1141,25 @@ module Gitlab ...@@ -1140,12 +1141,25 @@ module Gitlab
@has_visible_content = has_local_branches? @has_visible_content = has_local_branches?
end end
# Like all public `Gitlab::Git::Repository` methods, this method is part def fetch_repository_as_mirror(repository)
# of `Repository`'s interface through `method_missing`. remote_name = "tmp-#{SecureRandom.hex}"
# `Repository` has its own `fetch_remote` which uses `gitlab-shell` and
# takes some extra attributes, so we qualify this method name to prevent confusion. # Notice that this feature flag is not for `fetch_repository_as_mirror`
def fetch_remote_without_shell(remote = 'origin') # as a whole but for the fetching mechanism (file path or gitaly-ssh).
run_git(['fetch', remote]).last.zero? url, env = gitaly_migrate(:fetch_internal) do |is_enabled|
if is_enabled
repository = RemoteRepository.new(repository) unless repository.is_a?(RemoteRepository)
[GITALY_INTERNAL_URL, repository.fetch_env]
else
[repository.path, nil]
end
end
add_remote(remote_name, url)
set_remote_as_mirror(remote_name)
fetch_remote(remote_name, env: env)
ensure
remove_remote(remote_name)
end end
def blob_at(sha, path) def blob_at(sha, path)
...@@ -1849,7 +1863,7 @@ module Gitlab ...@@ -1849,7 +1863,7 @@ module Gitlab
end end
def gitaly_fetch_ref(source_repository, source_ref:, target_ref:) def gitaly_fetch_ref(source_repository, source_ref:, target_ref:)
args = %W(fetch --no-tags -f ssh://gitaly/internal.git #{source_ref}:#{target_ref}) args = %W(fetch --no-tags -f #{GITALY_INTERNAL_URL} #{source_ref}:#{target_ref})
run_git(args, env: source_repository.fetch_env) run_git(args, env: source_repository.fetch_env)
end end
...@@ -1869,6 +1883,10 @@ module Gitlab ...@@ -1869,6 +1883,10 @@ module Gitlab
rescue Rugged::ReferenceError rescue Rugged::ReferenceError
raise ArgumentError, 'Invalid merge source' raise ArgumentError, 'Invalid merge source'
end end
def fetch_remote(remote_name = 'origin', env: nil)
run_git(['fetch', remote_name], env: env).last.zero?
end
end end
end end
end end
...@@ -31,19 +31,6 @@ module Gitlab ...@@ -31,19 +31,6 @@ module Gitlab
end end
end end
# Like all_refs public `Gitlab::Git::Repository` methods, this method is part
# of `Repository`'s interface through `method_missing`.
# `Repository` has its own `fetch_as_mirror` which uses `gitlab-shell` and
# takes some extra attributes, so we qualify this method name to prevent confusion.
def fetch_as_mirror_without_shell(url)
remote_name = "tmp-#{SecureRandom.hex}"
add_remote(remote_name, url)
set_remote_as_mirror(remote_name)
fetch_remote_without_shell(remote_name)
ensure
remove_remote(remote_name) if remote_name
end
def remote_tags(remote) def remote_tags(remote)
# Each line has this format: "dc872e9fa6963f8f03da6c8f6f264d0845d6b092\trefs/tags/v1.10.0\n" # Each line has this format: "dc872e9fa6963f8f03da6c8f6f264d0845d6b092\trefs/tags/v1.10.0\n"
# We want to convert it to: [{ 'v1.10.0' => 'dc872e9fa6963f8f03da6c8f6f264d0845d6b092' }, ...] # We want to convert it to: [{ 'v1.10.0' => 'dc872e9fa6963f8f03da6c8f6f264d0845d6b092' }, ...]
......
...@@ -588,12 +588,12 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -588,12 +588,12 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
describe '#fetch_as_mirror_without_shell' do describe '#fetch_repository_as_mirror' do
let(:new_repository) do let(:new_repository) do
Gitlab::Git::Repository.new('default', 'my_project.git', '') Gitlab::Git::Repository.new('default', 'my_project.git', '')
end end
subject { new_repository.fetch_as_mirror_without_shell(repository.path) } subject { new_repository.fetch_repository_as_mirror(repository) }
before do before do
Gitlab::Shell.new.add_repository('default', 'my_project') Gitlab::Shell.new.add_repository('default', 'my_project')
...@@ -603,7 +603,7 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -603,7 +603,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
Gitlab::Shell.new.remove_repository(TestEnv.repos_path, 'my_project') Gitlab::Shell.new.remove_repository(TestEnv.repos_path, 'my_project')
end end
it 'fetches a url as a mirror remote' do it 'fetches a repository as a mirror remote' do
subject subject
expect(refs(new_repository.path)).to eq(refs(repository.path)) expect(refs(new_repository.path)).to eq(refs(repository.path))
...@@ -1662,21 +1662,6 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -1662,21 +1662,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
describe '#fetch_remote_without_shell' do
let(:git_path) { Gitlab.config.git.bin_path }
let(:remote_name) { 'my_remote' }
subject { repository.fetch_remote_without_shell(remote_name) }
it 'fetches the remote and returns true if the command was successful' do
expect(repository).to receive(:popen)
.with(%W(#{git_path} fetch #{remote_name}), repository.path, {})
.and_return(['', 0])
expect(subject).to be(true)
end
end
describe '#merge' do describe '#merge' do
let(:repository) do let(:repository) do
Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment