Commit f8fa6e6f authored by Alejandro Rodríguez's avatar Alejandro Rodríguez

Add internal endpoint to notify post-receive to Gitaly

parent b6a945b3
...@@ -350,3 +350,6 @@ gem 'health_check', '~> 2.2.0' ...@@ -350,3 +350,6 @@ gem 'health_check', '~> 2.2.0'
# System information # System information
gem 'vmstat', '~> 2.3.0' gem 'vmstat', '~> 2.3.0'
gem 'sys-filesystem', '~> 1.1.6' gem 'sys-filesystem', '~> 1.1.6'
# Gitaly GRPC client
gem 'gitaly', '~> 0.2.1'
...@@ -245,6 +245,9 @@ GEM ...@@ -245,6 +245,9 @@ GEM
json json
get_process_mem (0.2.0) get_process_mem (0.2.0)
gherkin-ruby (0.3.2) gherkin-ruby (0.3.2)
gitaly (0.2.1)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6) github-linguist (4.7.6)
charlock_holmes (~> 0.7.3) charlock_holmes (~> 0.7.3)
escape_utils (~> 1.1.0) escape_utils (~> 1.1.0)
...@@ -296,6 +299,7 @@ GEM ...@@ -296,6 +299,7 @@ GEM
multi_json (~> 1.10) multi_json (~> 1.10)
retriable (~> 1.4) retriable (~> 1.4)
signet (~> 0.6) signet (~> 0.6)
google-protobuf (3.2.0)
googleauth (0.5.1) googleauth (0.5.1)
faraday (~> 0.9) faraday (~> 0.9)
jwt (~> 1.4) jwt (~> 1.4)
...@@ -317,6 +321,9 @@ GEM ...@@ -317,6 +321,9 @@ GEM
grape-entity (0.6.0) grape-entity (0.6.0)
activesupport activesupport
multi_json (>= 1.3.2) multi_json (>= 1.3.2)
grpc (1.1.2)
google-protobuf (~> 3.1)
googleauth (~> 0.5.1)
haml (4.0.7) haml (4.0.7)
tilt tilt
haml_lint (0.21.0) haml_lint (0.21.0)
...@@ -877,6 +884,7 @@ DEPENDENCIES ...@@ -877,6 +884,7 @@ DEPENDENCIES
fuubar (~> 2.0.0) fuubar (~> 2.0.0)
gemnasium-gitlab-service (~> 0.2) gemnasium-gitlab-service (~> 0.2)
gemojione (~> 3.0) gemojione (~> 3.0)
gitaly (~> 0.2.1)
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.5.1) gitlab-markup (~> 1.5.1)
......
---
title: Add internal API to notify Gitaly of post receive
merge_request: 8983
author:
# Make sure we initialize a Gitaly channel before Sidekiq starts multi-threaded execution.
Gitlab::GitalyClient.channel unless Rails.env.test?
...@@ -132,6 +132,18 @@ module API ...@@ -132,6 +132,18 @@ module API
{ success: true, recovery_codes: codes } { success: true, recovery_codes: codes }
end end
post "/notify_post_receive" do
status 200
return unless Gitlab::GitalyClient.enabled?
begin
Gitlab::GitalyClient::Notifications.new.post_receive(params[:repo_path])
rescue GRPC::Unavailable => e
render_api_error(e, 500)
end
end
end end
end end
end end
require 'gitaly'
module Gitlab
module GitalyClient
def self.gitaly_address
if Gitlab.config.gitaly.socket_path
"unix://#{Gitlab.config.gitaly.socket_path}"
end
end
def self.channel
return @channel if defined?(@channel)
@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
def self.enabled?
gitaly_address.present?
end
end
end
module Gitlab
module GitalyClient
class Notifications
attr_accessor :stub
def initialize
@stub = Gitaly::Notifications::Stub.new(nil, nil, channel_override: GitalyClient.channel)
end
def post_receive(repo_path)
repository = Gitaly::Repository.new(path: repo_path)
request = Gitaly::PostReceiveRequest.new(repository: repository)
stub.post_receive(request)
end
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
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)
end
end
end
...@@ -409,6 +409,34 @@ describe API::Internal, api: true do ...@@ -409,6 +409,34 @@ describe API::Internal, api: true do
end end
end end
describe 'POST /notify_post_receive' do
let(:valid_params) do
{ repo_path: project.repository.path, secret_token: secret_token }
end
before do
allow(Gitlab.config.gitaly).to receive(:socket_path).and_return('path/to/gitaly.socket')
end
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)
post api("/internal/notify_post_receive"), valid_params
expect(response).to have_http_status(200)
end
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)
post api("/internal/notify_post_receive"), valid_params
expect(response).to have_http_status(500)
end
end
def project_with_repo_path(path) def project_with_repo_path(path)
double().tap do |fake_project| double().tap do |fake_project|
allow(fake_project).to receive_message_chain('repository.path_to_repo' => path) allow(fake_project).to receive_message_chain('repository.path_to_repo' => path)
......
RSpec::Matchers.define :post_receive_request_with_repo_path do |path|
match { |actual| actual.repository.path == path }
end
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