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 ...@@ -440,7 +440,7 @@ Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour
# Gitaly # Gitaly
# #
Settings['gitaly'] ||= Settingslogic.new({}) Settings['gitaly'] ||= Settingslogic.new({})
Settings.gitaly['socket_path'] ||= ENV['GITALY_SOCKET_PATH'] Settings.gitaly['enabled'] ||= false
# #
# Webpack settings # Webpack settings
......
# Make sure we initialize a Gitaly channel before Sidekiq starts multi-threaded execution. # 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 ...@@ -139,7 +139,7 @@ module API
return unless Gitlab::GitalyClient.enabled? return unless Gitlab::GitalyClient.enabled?
begin begin
Gitlab::GitalyClient::Notifications.new.post_receive(params[:repo_path]) Gitlab::GitalyClient::Notifications.new(params[:repo_path]).post_receive
rescue GRPC::Unavailable => e rescue GRPC::Unavailable => e
render_api_error(e, 500) render_api_error(e, 500)
end end
......
...@@ -4,28 +4,24 @@ module Gitlab ...@@ -4,28 +4,24 @@ module Gitlab
module GitalyClient module GitalyClient
SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze
def self.gitaly_address def self.configure_channel(shard, socket_path)
if Gitlab.config.gitaly.socket_path @channel ||= {}
"unix://#{Gitlab.config.gitaly.socket_path}" @channel[shard] = new_channel("unix://#{socket_path}")
end end
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(address, {}, :this_channel_is_insecure)
end end
def self.channel def self.get_channel(shard)
return @channel if defined?(@channel) @channel.fetch(shard)
@channel =
if enabled?
# 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
end
end end
def self.enabled? def self.enabled?
gitaly_address.present? Gitlab.config.gitaly.enabled
end end
def self.feature_enabled?(feature) def self.feature_enabled?(feature)
......
...@@ -7,8 +7,10 @@ module Gitlab ...@@ -7,8 +7,10 @@ module Gitlab
class << self class << self
def diff_from_parent(commit, options = {}) def diff_from_parent(commit, options = {})
stub = Gitaly::Diff::Stub.new(nil, nil, channel_override: GitalyClient.channel) project = commit.project
repo = Gitaly::Repository.new(path: commit.project.repository.path_to_repo) 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 = commit.parents[0]
parent_id = parent ? parent.id : EMPTY_TREE_ID parent_id = parent ? parent.id : EMPTY_TREE_ID
request = Gitaly::CommitDiffRequest.new( request = Gitaly::CommitDiffRequest.new(
......
...@@ -3,14 +3,19 @@ module Gitlab ...@@ -3,14 +3,19 @@ module Gitlab
class Notifications class Notifications
attr_accessor :stub attr_accessor :stub
def initialize def initialize(repo_path)
@stub = Gitaly::Notifications::Stub.new(nil, nil, channel_override: GitalyClient.channel) 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 end
def post_receive(repo_path) def post_receive
repository = Gitaly::Repository.new(path: repo_path) repository = Gitaly::Repository.new(path: @project.repository.path_to_repo)
request = Gitaly::PostReceiveRequest.new(repository: repository) request = Gitaly::PostReceiveRequest.new(repository: repository)
stub.post_receive(request) @stub.post_receive(request)
end end
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::GitalyClient::Notifications do 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 describe '#post_receive' do
let(:repo_path) { '/path/to/my_repo.git' }
it 'sends a post_receive message' do it 'sends a post_receive message' do
repo_path = create(:empty_project).repository.path_to_repo
expect_any_instance_of(Gitaly::Notifications::Stub). expect_any_instance_of(Gitaly::Notifications::Stub).
to receive(:post_receive).with(post_receive_request_with_repo_path(repo_path)) 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 end
end end
...@@ -429,7 +429,7 @@ describe API::Internal, api: true do ...@@ -429,7 +429,7 @@ describe API::Internal, api: true do
it "calls the Gitaly client if it's enabled" do it "calls the Gitaly client if it's enabled" do
expect_any_instance_of(Gitlab::GitalyClient::Notifications). 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 post api("/internal/notify_post_receive"), valid_params
...@@ -438,7 +438,7 @@ describe API::Internal, api: true do ...@@ -438,7 +438,7 @@ describe API::Internal, api: true do
it "returns 500 if the gitaly call fails" do it "returns 500 if the gitaly call fails" do
expect_any_instance_of(Gitlab::GitalyClient::Notifications). 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 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