Commit 8f50ef5e authored by Jacob Vosmaer's avatar Jacob Vosmaer

Separate GRPC channels per repository storage

parent c837da34
......@@ -440,7 +440,7 @@ Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour
# Gitaly
#
Settings['gitaly'] ||= Settingslogic.new({})
Settings.gitaly['socket_path'] ||= ENV['GITALY_SOCKET_PATH']
Settings.gitaly['enabled'] ||= false
#
# Webpack settings
......
# Make sure we initialize a Gitaly channel before Sidekiq starts multi-threaded execution.
Gitlab::GitalyClient.channel unless Rails.env.test?
Gitlab.config.repositories.storages.each do |name, params|
Gitlab::GitalyClient.configure_channel(name, params['socket_path'])
end
......@@ -139,7 +139,7 @@ module API
return unless Gitlab::GitalyClient.enabled?
begin
Gitlab::GitalyClient::Notifications.new.post_receive(params[:repo_path])
Gitlab::GitalyClient::Notifications.new(params[:repo_path]).post_receive
rescue GRPC::Unavailable => e
render_api_error(e, 500)
end
......
......@@ -4,28 +4,24 @@ module Gitlab
module GitalyClient
SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze
def self.gitaly_address
if Gitlab.config.gitaly.socket_path
"unix://#{Gitlab.config.gitaly.socket_path}"
def self.configure_channel(shard, socket_path)
@channel ||= {}
@channel[shard] = new_channel("unix://#{socket_path}")
end
end
def self.channel
return @channel if defined?(@channel)
@channel =
if enabled?
def self.new_channel(address)
# NOTE: Gitaly currently runs on a Unix socket, so permissions are
# handled using the file system and no additional authentication is
# required (therefore the :this_channel_is_insecure flag)
GRPC::Core::Channel.new(gitaly_address, {}, :this_channel_is_insecure)
else
nil
GRPC::Core::Channel.new(address, {}, :this_channel_is_insecure)
end
def self.get_channel(shard)
@channel.fetch(shard)
end
def self.enabled?
gitaly_address.present?
Gitlab.config.gitaly.enabled
end
def self.feature_enabled?(feature)
......
......@@ -7,8 +7,10 @@ module Gitlab
class << self
def diff_from_parent(commit, options = {})
stub = Gitaly::Diff::Stub.new(nil, nil, channel_override: GitalyClient.channel)
repo = Gitaly::Repository.new(path: commit.project.repository.path_to_repo)
project = commit.project
channel = GitalyClient.get_channel(project.repository_storage)
stub = Gitaly::Diff::Stub.new(nil, nil, channel_override: channel)
repo = Gitaly::Repository.new(path: project.repository.path_to_repo)
parent = commit.parents[0]
parent_id = parent ? parent.id : EMPTY_TREE_ID
request = Gitaly::CommitDiffRequest.new(
......
......@@ -3,14 +3,19 @@ module Gitlab
class Notifications
attr_accessor :stub
def initialize
@stub = Gitaly::Notifications::Stub.new(nil, nil, channel_override: GitalyClient.channel)
def initialize(repo_path)
full_path = Gitlab::RepoPath.strip_storage_path(repo_path).
sub(/\.git\z/, '').sub(/\.wiki\z/, '')
@project = Project.find_by_full_path(full_path)
channel = GitalyClient.get_channel(@project.repository_storage)
@stub = Gitaly::Notifications::Stub.new(nil, nil, channel_override: channel)
end
def post_receive(repo_path)
repository = Gitaly::Repository.new(path: repo_path)
def post_receive
repository = Gitaly::Repository.new(path: @project.repository.path_to_repo)
request = Gitaly::PostReceiveRequest.new(repository: repository)
stub.post_receive(request)
@stub.post_receive(request)
end
end
end
......
require 'spec_helper'
describe Gitlab::GitalyClient::Notifications do
let(:client) { Gitlab::GitalyClient::Notifications.new }
before do
allow(Gitlab.config.gitaly).to receive(:socket_path).and_return('path/to/gitaly.socket')
end
describe '#post_receive' do
let(:repo_path) { '/path/to/my_repo.git' }
it 'sends a post_receive message' do
repo_path = create(:empty_project).repository.path_to_repo
expect_any_instance_of(Gitaly::Notifications::Stub).
to receive(:post_receive).with(post_receive_request_with_repo_path(repo_path))
client.post_receive(repo_path)
described_class.new(repo_path).post_receive
end
end
end
......@@ -429,7 +429,7 @@ describe API::Internal, api: true do
it "calls the Gitaly client if it's enabled" do
expect_any_instance_of(Gitlab::GitalyClient::Notifications).
to receive(:post_receive).with(project.repository.path)
to receive(:post_receive)
post api("/internal/notify_post_receive"), valid_params
......@@ -438,7 +438,7 @@ describe API::Internal, api: true do
it "returns 500 if the gitaly call fails" do
expect_any_instance_of(Gitlab::GitalyClient::Notifications).
to receive(:post_receive).with(project.repository.path).and_raise(GRPC::Unavailable)
to receive(:post_receive).and_raise(GRPC::Unavailable)
post api("/internal/notify_post_receive"), valid_params
......
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