As we reevaluate how to best support and maintain Staging Ref in the future, we encourage development teams using this environment to highlight their use cases in the following issue: https://gitlab.com/gitlab-com/gl-infra/software-delivery/framework/software-delivery-framework-issue-tracker/-/issues/36.

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • idrozdov/gitlab-shell
  • mmj/gitlab-shell
2 results
Show changes
Commits on Source (3)
Loading
Loading
@@ -15,7 +15,7 @@ begin
else
abort "FAILED. code: #{resp.code}"
end
rescue GitlabNet::ApiUnreachableError
rescue HttpClient::ApiUnreachableError
abort "FAILED: Failed to connect to internal API"
end
Loading
Loading
require_relative 'http_client'
class GitalyClient < HttpClient
attr_reader :gitaly_url
def initialize(gitaly_url)
@gitaly_url = gitaly_url
end
def notify_post_receive(repo_path)
url = "#{gitaly_url}/post-receive"
params = { project: sanitize_path(repo_path) }
# NOTE: Consider being more permisive with gitaly once it's more robust
resp = post(url, params, read_timeout: 5)
resp.code == '200'
end
end
Loading
Loading
@@ -33,7 +33,7 @@ class GitlabAccess
raise AccessDeniedError, status.message unless status.allowed?
true
rescue GitlabNet::ApiUnreachableError
rescue HttpClient::ApiUnreachableError
$stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable"
false
rescue AccessDeniedError => ex
Loading
Loading
require 'net/http'
require 'openssl'
require 'json'
require_relative 'gitlab_config'
require_relative 'gitlab_logger'
require_relative 'gitlab_access'
require_relative 'gitlab_redis'
require_relative 'gitlab_lfs_authentication'
require_relative 'httpunix'
class GitlabNet
class ApiUnreachableError < StandardError; end
CHECK_TIMEOUT = 5
READ_TIMEOUT = 300
require_relative 'http_client'
class GitlabNet < HttpClient
def check_access(cmd, repo, actor, changes, protocol, env: {})
changes = changes.join("\n") unless changes.kind_of?(String)
Loading
Loading
@@ -93,6 +84,20 @@ class GitlabNet
{}
end
def gitaly_socket_path
return @gitaly_socket_path if defined?(@gitaly_socket_path)
@gitaly_socket_path = begin
resp = get("#{host}/gitaly")
if resp.code == '200' && (socket_path = JSON.parse(resp.body)['socket_path'])
"http+unix://#{socket_path.gsub('/', '%2F')}"
else
nil
end
end
end
def redis_client
redis_config = config.redis
database = redis_config['database'] || 0
Loading
Loading
@@ -119,114 +124,15 @@ class GitlabNet
protected
def sanitize_path(repo)
repo.gsub("'", "")
end
def config
@config ||= GitlabConfig.new
def http_request_for(method, uri, params = {})
super(method, uri, params.merge(secret_token: secret_token))
end
def host
"#{config.gitlab_url}/api/v3/internal"
end
def http_client_for(uri, options={})
if uri.is_a?(URI::HTTPUNIX)
http = Net::HTTPUNIX.new(uri.hostname)
else
http = Net::HTTP.new(uri.host, uri.port)
end
http.read_timeout = options[:read_timeout] || read_timeout
if uri.is_a?(URI::HTTPS)
http.use_ssl = true
http.cert_store = cert_store
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if config.http_settings['self_signed_cert']
end
http
end
def http_request_for(method, uri, params = {})
request_klass = method == :get ? Net::HTTP::Get : Net::HTTP::Post
request = request_klass.new(uri.request_uri)
user = config.http_settings['user']
password = config.http_settings['password']
request.basic_auth(user, password) if user && password
request.set_form_data(params.merge(secret_token: secret_token))
if uri.is_a?(URI::HTTPUNIX)
# The HTTPUNIX HTTP client does not set a correct Host header. This can
# lead to 400 Bad Request responses.
request['Host'] = 'localhost'
end
request
end
def request(method, url, params = {}, options={})
$logger.debug "Performing #{method.to_s.upcase} #{url}"
uri = URI.parse(url)
http = http_client_for(uri, options)
request = http_request_for(method, uri, params)
begin
start_time = Time.new
response = http.start { http.request(request) }
rescue => e
$logger.warn "Failed to connect to internal API <#{method.to_s.upcase} #{url}>: #{e.inspect}"
raise ApiUnreachableError
ensure
$logger.info do
sprintf('%s %s %0.5f', method.to_s.upcase, url, Time.new - start_time)
end
end
if response.code == "200"
$logger.debug "Received response #{response.code} => <#{response.body}>."
else
$logger.error "API call <#{method.to_s.upcase} #{url}> failed: #{response.code} => <#{response.body}>."
end
response
end
def get(url, options={})
request(:get, url, {}, options)
end
def post(url, params)
request(:post, url, params)
end
def cert_store
@cert_store ||= begin
store = OpenSSL::X509::Store.new
store.set_default_paths
if ca_file = config.http_settings['ca_file']
store.add_file(ca_file)
end
if ca_path = config.http_settings['ca_path']
store.add_path(ca_path)
end
store
end
end
def secret_token
@secret_token ||= File.read config.secret_file
end
def read_timeout
config.http_settings['read_timeout'] || READ_TIMEOUT
end
end
require_relative 'gitlab_init'
require_relative 'gitlab_net'
require_relative 'gitaly_client'
require_relative 'gitlab_reference_counter'
require_relative 'gitlab_metrics'
require 'json'
Loading
Loading
@@ -35,7 +36,10 @@ class GitlabPostReceive
api.merge_request_urls(@repo_path, @changes)
end
print_merge_request_links(merge_request_urls)
rescue GitlabNet::ApiUnreachableError
# NOTE: Consider checking Gitaly's success once it's robust and mandatory
notify_gitaly
rescue HttpClient::ApiUnreachableError
nil
end
Loading
Loading
@@ -121,4 +125,21 @@ class GitlabPostReceive
false
end
end
def notify_gitaly
return true unless gitaly_client
gitaly_client.notify_post_receive(repo_path)
end
def gitaly_client
unless defined?(@gitaly_client)
socket_path = api.gitaly_socket_path
@gitaly_client = socket_path && GitalyClient.new(socket_path)
end
@gitaly_client
rescue HttpClient::ApiUnreachableError
nil
end
end
Loading
Loading
@@ -40,7 +40,7 @@ class GitlabShell
process_cmd(args)
true
rescue GitlabNet::ApiUnreachableError => ex
rescue HttpClient::ApiUnreachableError => ex
$stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable"
false
rescue AccessDeniedError => ex
Loading
Loading
@@ -174,7 +174,7 @@ class GitlabShell
begin
@user = api.discover(@key_id)
rescue GitlabNet::ApiUnreachableError
rescue HttpClient::ApiUnreachableError
@user = nil
end
end
Loading
Loading
require 'net/http'
require 'openssl'
require_relative 'gitlab_config'
require_relative 'gitlab_logger'
require_relative 'httpunix'
class HttpClient
class ApiUnreachableError < StandardError; end
CHECK_TIMEOUT = 5
READ_TIMEOUT = 300
protected
def sanitize_path(repo)
repo.gsub("'", "")
end
def config
@config ||= GitlabConfig.new
end
def http_client_for(uri, options={})
if uri.is_a?(URI::HTTPUNIX)
http = Net::HTTPUNIX.new(uri.hostname)
else
http = Net::HTTP.new(uri.host, uri.port)
end
http.read_timeout = options[:read_timeout] || read_timeout
if uri.is_a?(URI::HTTPS)
http.use_ssl = true
http.cert_store = cert_store
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if config.http_settings['self_signed_cert']
end
http
end
def http_request_for(method, uri, params = {})
request_klass = method == :get ? Net::HTTP::Get : Net::HTTP::Post
request = request_klass.new(uri.request_uri)
user = config.http_settings['user']
password = config.http_settings['password']
request.basic_auth(user, password) if user && password
request.set_form_data(params)
if uri.is_a?(URI::HTTPUNIX)
# The HTTPUNIX HTTP client does not set a correct Host header. This can
# lead to 400 Bad Request responses.
request['Host'] = 'localhost'
end
request
end
def request(method, url, params = {}, options={})
$logger.debug "Performing #{method.to_s.upcase} #{url}"
uri = URI.parse(url)
http = http_client_for(uri, options)
request = http_request_for(method, uri, params)
begin
start_time = Time.new
response = http.start { http.request(request) }
rescue => e
$logger.warn "Failed to connect to <#{method.to_s.upcase} #{url}>: #{e.inspect}"
raise ApiUnreachableError
ensure
$logger.info do
sprintf('%s %s %0.5f', method.to_s.upcase, url, Time.new - start_time)
end
end
if response.code == "200"
$logger.debug "Received response #{response.code} => <#{response.body}>."
else
$logger.error "HTTP call <#{method.to_s.upcase} #{url}> failed: #{response.code} => <#{response.body}>."
end
response
end
def get(url, options={})
request(:get, url, {}, options)
end
def post(url, params, options = {})
request(:post, url, params, options)
end
def cert_store
@cert_store ||= begin
store = OpenSSL::X509::Store.new
store.set_default_paths
if ca_file = config.http_settings['ca_file']
store.add_file(ca_file)
end
if ca_path = config.http_settings['ca_path']
store.add_path(ca_path)
end
store
end
end
def read_timeout
config.http_settings['read_timeout'] || READ_TIMEOUT
end
end
require_relative 'spec_helper'
require_relative '../lib/gitaly_client'
describe GitalyClient, vcr: true do
include WebMock::API
let(:gitaly_client) { GitalyClient.new('http+unix://%2Fpath%2Fto%2Fgitaly.socket') }
let(:repo_url) { 'gitlab/gitlabhq.git' }
describe :notify_post_receive do
before do
stub_request(:post, /.*/)
end
it 'should return 200 code for gitlab check' do
Net::HTTP::Post.any_instance.should_receive(:set_form_data).with(project: repo_url)
gitaly_client.notify_post_receive(repo_url)
end
it "raises an exception if the connection fails" do
Net::HTTP.any_instance.stub(:request).and_raise(StandardError)
expect { gitaly_client.notify_post_receive(repo_url) }.to raise_error(GitalyClient::ApiUnreachableError)
end
after do
WebMock.reset!
end
end
end
Loading
Loading
@@ -49,7 +49,7 @@ describe GitlabAccess do
context "API connection fails" do
before do
api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError)
api.stub(:check_access).and_raise(HttpClient::ApiUnreachableError)
end
it "returns false" do
Loading
Loading
Loading
Loading
@@ -29,7 +29,7 @@ describe GitlabNet, vcr: true do
it "raises an exception if the connection fails" do
Net::HTTP.any_instance.stub(:request).and_raise(StandardError)
expect { gitlab_net.check }.to raise_error(GitlabNet::ApiUnreachableError)
expect { gitlab_net.check }.to raise_error(HttpClient::ApiUnreachableError)
end
end
Loading
Loading
@@ -52,7 +52,7 @@ describe GitlabNet, vcr: true do
it "raises an exception if the connection fails" do
VCR.use_cassette("discover-ok") do
Net::HTTP.any_instance.stub(:request).and_raise(StandardError)
expect { gitlab_net.discover('key-126') }.to raise_error(GitlabNet::ApiUnreachableError)
expect { gitlab_net.discover('key-126') }.to raise_error(HttpClient::ApiUnreachableError)
end
end
end
Loading
Loading
@@ -225,7 +225,7 @@ describe GitlabNet, vcr: true do
Net::HTTP.any_instance.stub(:request).and_raise(StandardError)
expect {
gitlab_net.check_access('git-upload-pack', 'gitlab/gitlabhq.git', 'user-1', changes, 'ssh')
}.to raise_error(GitlabNet::ApiUnreachableError)
}.to raise_error(HttpClient::ApiUnreachableError)
end
end
Loading
Loading
Loading
Loading
@@ -17,9 +17,10 @@ describe GitlabPostReceive do
before do
GitlabConfig.any_instance.stub(repos_path: repository_path)
GitlabNet.any_instance.stub(gitaly_socket_path: 'http+unix://%2Fpath%2Fto%2Fgitaly.socket')
GitlabNet.any_instance.stub(broadcast_message: { })
GitlabNet.any_instance.stub(:merge_request_urls).with(repo_path, wrongly_encoded_changes) { [] }
expect(Time).to receive(:now).and_return(enqueued_at)
allow(Time).to receive(:now).and_return(enqueued_at)
end
describe "#exec" do
Loading
Loading
@@ -47,6 +48,8 @@ describe GitlabPostReceive do
it "prints the new merge request url" do
expect(redis_client).to receive(:rpush)
expect_any_instance_of(GitalyClient).to receive(:notify_post_receive).with(repo_path)
expect(gitlab_post_receive).to receive(:puts).ordered
expect(gitlab_post_receive).to receive(:puts).with(
"To create a merge request for new_branch, visit:"
Loading
Loading
@@ -74,6 +77,8 @@ describe GitlabPostReceive do
it "prints the view merge request url" do
expect(redis_client).to receive(:rpush)
expect_any_instance_of(GitalyClient).to receive(:notify_post_receive).with(repo_path)
expect(gitlab_post_receive).to receive(:puts).ordered
expect(gitlab_post_receive).to receive(:puts).with(
"View merge request for feature_branch:"
Loading
Loading
@@ -103,6 +108,8 @@ describe GitlabPostReceive do
it 'prints the broadcast message and create new merge request link' do
expect(redis_client).to receive(:rpush)
expect_any_instance_of(GitalyClient).to receive(:notify_post_receive).with(repo_path)
expect(gitlab_post_receive).to receive(:puts).ordered
expect(gitlab_post_receive).to receive(:puts).with(
"========================================================================"
Loading
Loading
Loading
Loading
@@ -217,7 +217,7 @@ describe GitlabShell do
let(:ssh_cmd) { 'git-upload-pack gitlab-ci.git' }
before {
api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError)
api.stub(:check_access).and_raise(HttpClient::ApiUnreachableError)
}
after { subject.exec(ssh_cmd) }
Loading
Loading