summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/api/api_guard.rb2
-rw-r--r--lib/api/entities.rb3
-rw-r--r--lib/api/helpers.rb5
-rw-r--r--lib/api/internal.rb2
-rw-r--r--lib/api/issues.rb4
-rw-r--r--lib/api/labels.rb9
-rw-r--r--lib/api/merge_requests.rb35
-rw-r--r--lib/api/notes.rb14
-rw-r--r--lib/api/settings.rb3
-rw-r--r--lib/api/users.rb2
-rw-r--r--lib/api/v3/issues.rb4
-rw-r--r--lib/backup/repository.rb4
-rw-r--r--lib/banzai/filter/merge_request_reference_filter.rb29
-rw-r--r--lib/banzai/filter/user_reference_filter.rb4
-rw-r--r--lib/gitlab/bitbucket_import/importer.rb9
-rw-r--r--lib/gitlab/etag_caching/middleware.rb11
-rw-r--r--lib/gitlab/git/repository.rb35
-rw-r--r--lib/gitlab/git/tree.rb2
-rw-r--r--lib/gitlab/gitaly_client.rb34
-rw-r--r--lib/gitlab/gitaly_client/commit.rb20
-rw-r--r--lib/gitlab/gitaly_client/notifications.rb15
-rw-r--r--lib/gitlab/github_import/branch_formatter.rb8
-rw-r--r--lib/gitlab/github_import/pull_request_formatter.rb33
-rw-r--r--lib/gitlab/ldap/config.rb4
-rw-r--r--lib/gitlab/polling_interval.rb22
-rw-r--r--lib/gitlab/repo_path.rb23
-rw-r--r--lib/gitlab/uploads_transfer.rb2
-rw-r--r--lib/gitlab/workhorse.rb19
-rw-r--r--lib/tasks/gitlab/check.rake4
-rw-r--r--lib/tasks/karma.rake5
30 files changed, 236 insertions, 130 deletions
diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb
index 409cb5b924f..9fcf04efa38 100644
--- a/lib/api/api_guard.rb
+++ b/lib/api/api_guard.rb
@@ -121,7 +121,7 @@ module API
end
def oauth2_bearer_token_error_handler
- Proc.new do |e|
+ proc do |e|
response =
case e
when MissingTokenError
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 5954aea8041..00d44821e3f 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -204,7 +204,7 @@ module API
expose :id, :name, :type, :path
expose :mode do |obj, options|
- filemode = obj.mode.to_s(8)
+ filemode = obj.mode
filemode = "0" + filemode if filemode.length < 6
filemode
end
@@ -581,6 +581,7 @@ module API
expose :plantuml_enabled
expose :plantuml_url
expose :terminal_max_session_time
+ expose :polling_interval_multiplier
end
class Release < Grape::Entity
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index bd22b82476b..61527c1e20b 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -90,6 +90,11 @@ module API
MergeRequestsFinder.new(current_user, project_id: user_project.id).find_by!(iid: iid)
end
+ def find_project_snippet(id)
+ finder_params = { filter: :by_project, project: user_project }
+ SnippetsFinder.new.execute(current_user, finder_params).find(id)
+ end
+
def find_merge_request_with_access(iid, access_level = :read_merge_request)
merge_request = user_project.merge_requests.find_by!(iid: iid)
authorize! access_level, merge_request
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index 7eed93aba00..523f38d129e 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -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
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index fd2674910d2..4dce5dd130a 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -63,14 +63,14 @@ module API
success Entities::IssueBasic
end
params do
- optional :state, type: String, values: %w[opened closed all], default: 'opened',
+ optional :state, type: String, values: %w[opened closed all], default: 'all',
desc: 'Return opened, closed, or all issues'
use :issues_params
end
get ":id/issues" do
group = find_group!(params[:id])
- issues = find_issues(group_id: group.id, state: params[:state] || 'opened')
+ issues = find_issues(group_id: group.id)
present paginate(issues), with: Entities::IssueBasic, current_user: current_user
end
diff --git a/lib/api/labels.rb b/lib/api/labels.rb
index d9a3cb7bb6b..20b25529d0c 100644
--- a/lib/api/labels.rb
+++ b/lib/api/labels.rb
@@ -23,7 +23,7 @@ module API
end
params do
requires :name, type: String, desc: 'The name of the label to be created'
- requires :color, type: String, desc: "The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB)"
+ requires :color, type: String, desc: "The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the allowed CSS color names"
optional :description, type: String, desc: 'The description of label to be created'
optional :priority, type: Integer, desc: 'The priority of the label', allow_blank: true
end
@@ -34,7 +34,7 @@ module API
conflict!('Label already exists') if label
priority = params.delete(:priority)
- label = user_project.labels.create(declared_params(include_missing: false))
+ label = ::Labels::CreateService.new(declared_params(include_missing: false)).execute(project: user_project)
if label.valid?
label.prioritize!(user_project, priority) if priority
@@ -65,7 +65,7 @@ module API
params do
requires :name, type: String, desc: 'The name of the label to be updated'
optional :new_name, type: String, desc: 'The new name of the label'
- optional :color, type: String, desc: "The new color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB)"
+ optional :color, type: String, desc: "The new color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the allowed CSS color names"
optional :description, type: String, desc: 'The new description of label'
optional :priority, type: Integer, desc: 'The priority of the label', allow_blank: true
at_least_one_of :new_name, :color, :description, :priority
@@ -82,7 +82,8 @@ module API
# Rename new name to the actual label attribute name
label_params[:name] = label_params.delete(:new_name) if label_params.key?(:new_name)
- render_validation_error!(label) unless label.update(label_params)
+ label = ::Labels::UpdateService.new(label_params).execute(label)
+ render_validation_error!(label) unless label.valid?
if update_priority
if priority.nil?
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 5cc807d5bff..c8033664133 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -226,41 +226,6 @@ module API
.cancel(merge_request)
end
- desc 'Get the comments of a merge request' do
- success Entities::MRNote
- end
- params do
- use :pagination
- end
- get ':id/merge_requests/:merge_request_iid/comments' do
- merge_request = find_merge_request_with_access(params[:merge_request_iid])
- present paginate(merge_request.notes.fresh), with: Entities::MRNote
- end
-
- desc 'Post a comment to a merge request' do
- success Entities::MRNote
- end
- params do
- requires :note, type: String, desc: 'The text of the comment'
- end
- post ':id/merge_requests/:merge_request_iid/comments' do
- merge_request = find_merge_request_with_access(params[:merge_request_iid], :create_note)
-
- opts = {
- note: params[:note],
- noteable_type: 'MergeRequest',
- noteable_id: merge_request.id
- }
-
- note = ::Notes::CreateService.new(user_project, current_user, opts).execute
-
- if note.save
- present note, with: Entities::MRNote
- else
- render_api_error!("Failed to save note #{note.errors.messages}", 400)
- end
- end
-
desc 'List issues that will be closed on merge' do
success Entities::MRNote
end
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 29ceffdbd2d..de39e579ac3 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -21,7 +21,7 @@ module API
use :pagination
end
get ":id/#{noteables_str}/:noteable_id/notes" do
- noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id])
+ noteable = find_project_noteable(noteables_str, params[:noteable_id])
if can?(current_user, noteable_read_ability_name(noteable), noteable)
# We exclude notes that are cross-references and that cannot be viewed
@@ -49,7 +49,7 @@ module API
requires :noteable_id, type: Integer, desc: 'The ID of the noteable'
end
get ":id/#{noteables_str}/:noteable_id/notes/:note_id" do
- noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id])
+ noteable = find_project_noteable(noteables_str, params[:noteable_id])
note = noteable.notes.find(params[:note_id])
can_read_note = can?(current_user, noteable_read_ability_name(noteable), noteable) && !note.cross_reference_not_visible_for?(current_user)
@@ -69,14 +69,14 @@ module API
optional :created_at, type: String, desc: 'The creation date of the note'
end
post ":id/#{noteables_str}/:noteable_id/notes" do
+ noteable = find_project_noteable(noteables_str, params[:noteable_id])
+
opts = {
note: params[:body],
noteable_type: noteables_str.classify,
- noteable_id: params[:noteable_id]
+ noteable_id: noteable.id
}
- noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id])
-
if can?(current_user, noteable_read_ability_name(noteable), noteable)
if params[:created_at] && (current_user.is_admin? || user_project.owner == current_user)
opts[:created_at] = params[:created_at]
@@ -137,6 +137,10 @@ module API
end
helpers do
+ def find_project_noteable(noteables_str, noteable_id)
+ public_send("find_project_#{noteables_str.singularize}", noteable_id)
+ end
+
def noteable_read_ability_name(noteable)
"read_#{noteable.class.to_s.underscore}".to_sym
end
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index d4d3229f0d1..c7f97ad2aab 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -110,6 +110,7 @@ module API
requires :housekeeping_gc_period, type: Integer, desc: "Number of Git pushes after which 'git gc' is run."
end
optional :terminal_max_session_time, type: Integer, desc: 'Maximum time for web terminal websocket connection (in seconds). Set to 0 for unlimited time.'
+ optional :polling_interval_multiplier, type: BigDecimal, desc: 'Interval multiplier used by endpoints that perform polling. Set to 0 to disable polling.'
at_least_one_of :default_branch_protection, :default_project_visibility, :default_snippet_visibility,
:default_group_visibility, :restricted_visibility_levels, :import_sources,
:enabled_git_access_protocol, :gravatar_enabled, :default_projects_limit,
@@ -125,7 +126,7 @@ module API
:akismet_enabled, :admin_notification_email, :sentry_enabled,
:repository_storage, :repository_checks_enabled, :koding_enabled, :plantuml_enabled,
:version_check_enabled, :email_author_in_body, :html_emails_enabled,
- :housekeeping_enabled, :terminal_max_session_time
+ :housekeeping_enabled, :terminal_max_session_time, :polling_interval_multiplier
end
put "application/settings" do
attrs = declared_params(include_missing: false)
diff --git a/lib/api/users.rb b/lib/api/users.rb
index a4201fe6fed..530ca0b5235 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -293,7 +293,7 @@ module API
user = User.find_by(id: params[:id])
not_found!('User') unless user
- ::Users::DestroyService.new(current_user).execute(user)
+ DeleteUserWorker.perform_async(current_user.id, user.id)
end
desc 'Block a user. Available only for admins.'
diff --git a/lib/api/v3/issues.rb b/lib/api/v3/issues.rb
index 54c6a8060b8..715083fc4f8 100644
--- a/lib/api/v3/issues.rb
+++ b/lib/api/v3/issues.rb
@@ -73,14 +73,14 @@ module API
success ::API::Entities::Issue
end
params do
- optional :state, type: String, values: %w[opened closed all], default: 'opened',
+ optional :state, type: String, values: %w[opened closed all], default: 'all',
desc: 'Return opened, closed, or all issues'
use :issues_params
end
get ":id/issues" do
group = find_group!(params[:id])
- issues = find_issues(group_id: group.id, state: params[:state] || 'opened', match_all_labels: true)
+ issues = find_issues(group_id: group.id, match_all_labels: true)
present paginate(issues), with: ::API::Entities::Issue, current_user: current_user
end
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index cd745d35e7c..6b29600a751 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -182,7 +182,9 @@ module Backup
dir_entries = Dir.entries(path)
- yield('custom_hooks') if dir_entries.include?('custom_hooks')
+ if dir_entries.include?('custom_hooks') || dir_entries.include?('custom_hooks.tar')
+ yield('custom_hooks')
+ end
end
def prepare
diff --git a/lib/banzai/filter/merge_request_reference_filter.rb b/lib/banzai/filter/merge_request_reference_filter.rb
index ac5216d9cfb..3888acf935e 100644
--- a/lib/banzai/filter/merge_request_reference_filter.rb
+++ b/lib/banzai/filter/merge_request_reference_filter.rb
@@ -11,8 +11,8 @@ module Banzai
MergeRequest
end
- def find_object(project, id)
- project.merge_requests.find_by(iid: id)
+ def find_object(project, iid)
+ merge_requests_per_project[project][iid]
end
def url_for_object(mr, project)
@@ -21,6 +21,31 @@ module Banzai
only_path: context[:only_path])
end
+ def project_from_ref(ref)
+ projects_per_reference[ref || current_project_path]
+ end
+
+ # Returns a Hash containing the merge_requests per Project instance.
+ def merge_requests_per_project
+ @merge_requests_per_project ||= begin
+ hash = Hash.new { |h, k| h[k] = {} }
+
+ projects_per_reference.each do |path, project|
+ merge_request_ids = references_per_project[path]
+
+ merge_requests = project.merge_requests
+ .where(iid: merge_request_ids.to_a)
+ .includes(target_project: :namespace)
+
+ merge_requests.each do |merge_request|
+ hash[project][merge_request.iid.to_i] = merge_request
+ end
+ end
+
+ hash
+ end
+ end
+
def object_link_text_extras(object, matches)
extras = super
diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb
index fe1f0923136..a798927823f 100644
--- a/lib/banzai/filter/user_reference_filter.rb
+++ b/lib/banzai/filter/user_reference_filter.rb
@@ -60,7 +60,7 @@ module Banzai
self.class.references_in(text) do |match, username|
if username == 'all' && !skip_project_check?
link_to_all(link_content: link_content)
- elsif namespace = namespaces[username]
+ elsif namespace = namespaces[username.downcase]
link_to_namespace(namespace, link_content: link_content) || match
else
match
@@ -74,7 +74,7 @@ module Banzai
# The keys of this Hash are the namespace paths, the values the
# corresponding Namespace objects.
def namespaces
- @namespaces ||= Namespace.where_full_path_in(usernames).index_by(&:full_path)
+ @namespaces ||= Namespace.where_full_path_in(usernames).index_by(&:full_path).transform_keys(&:downcase)
end
# Returns all usernames referenced in the current document.
diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb
index 44323b47dca..f4efa20374a 100644
--- a/lib/gitlab/bitbucket_import/importer.rb
+++ b/lib/gitlab/bitbucket_import/importer.rb
@@ -130,8 +130,13 @@ module Gitlab
end
def create_labels
- LABELS.each do |label|
- @labels[label[:title]] = project.labels.create!(label)
+ LABELS.each do |label_params|
+ label = ::Labels::CreateService.new(label_params).execute(project: project)
+ if label.valid?
+ @labels[label_params[:title]] = label
+ else
+ raise "Failed to create label \"#{label_params[:title]}\" for project \"#{project.name_with_namespace}\""
+ end
end
end
diff --git a/lib/gitlab/etag_caching/middleware.rb b/lib/gitlab/etag_caching/middleware.rb
index ffbc6e17dc5..9c98f0d1a30 100644
--- a/lib/gitlab/etag_caching/middleware.rb
+++ b/lib/gitlab/etag_caching/middleware.rb
@@ -18,8 +18,7 @@ module Gitlab
if_none_match = env['HTTP_IF_NONE_MATCH']
if if_none_match == etag
- Gitlab::Metrics.add_event(:etag_caching_cache_hit)
- [304, { 'ETag' => etag }, ['']]
+ handle_cache_hit(etag)
else
track_cache_miss(if_none_match, cached_value_present)
@@ -52,6 +51,14 @@ module Gitlab
%Q{W/"#{value}"}
end
+ def handle_cache_hit(etag)
+ Gitlab::Metrics.add_event(:etag_caching_cache_hit)
+
+ status_code = Gitlab::PollingInterval.polling_enabled? ? 304 : 429
+
+ [status_code, { 'ETag' => etag }, ['']]
+ end
+
def track_cache_miss(if_none_match, cached_value_present)
if if_none_match.blank?
Gitlab::Metrics.add_event(:etag_caching_header_missing)
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 2187dd70ff4..32aebb6f6f0 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -320,7 +320,7 @@ module Gitlab
def log_by_walk(sha, options)
walk_options = {
show: sha,
- sort: Rugged::SORT_DATE,
+ sort: Rugged::SORT_NONE,
limit: options[:limit],
offset: options[:offset]
}
@@ -346,7 +346,12 @@ module Gitlab
cmd << "--after=#{options[:after].iso8601}" if options[:after]
cmd << "--before=#{options[:before].iso8601}" if options[:before]
cmd << sha
- cmd += %W[-- #{options[:path]}] if options[:path].present?
+
+ # :path can be a string or an array of strings
+ if options[:path].present?
+ cmd << '--'
+ cmd += Array(options[:path])
+ end
raw_output = IO.popen(cmd) { |io| io.read }
lines = offset_in_ruby ? raw_output.lines.drop(offset) : raw_output.lines
@@ -382,7 +387,7 @@ module Gitlab
# a detailed list of valid arguments.
def commits_between(from, to)
walker = Rugged::Walker.new(rugged)
- walker.sorting(Rugged::SORT_DATE | Rugged::SORT_REVERSE)
+ walker.sorting(Rugged::SORT_NONE | Rugged::SORT_REVERSE)
sha_from = sha_from_ref(from)
sha_to = sha_from_ref(to)
@@ -406,6 +411,11 @@ module Gitlab
rugged.merge_base(from, to)
end
+ # Returns true is +from+ is direct ancestor to +to+, otherwise false
+ def is_ancestor?(from, to)
+ Gitlab::GitalyClient::Commit.is_ancestor(self, from, to)
+ end
+
# Return an array of Diff objects that represent the diff
# between +from+ and +to+. See Diff::filter_diff_options for the allowed
# diff options. The +options+ hash can also include :break_rewrites to
@@ -460,7 +470,7 @@ module Gitlab
if actual_options[:order] == :topo
walker.sorting(Rugged::SORT_TOPO)
else
- walker.sorting(Rugged::SORT_DATE)
+ walker.sorting(Rugged::SORT_NONE)
end
commits = []
@@ -828,23 +838,6 @@ module Gitlab
Rugged::Commit.create(rugged, actual_options)
end
- def commits_since(from_date)
- walker = Rugged::Walker.new(rugged)
- walker.sorting(Rugged::SORT_DATE | Rugged::SORT_REVERSE)
-
- rugged.references.each("refs/heads/*") do |ref|
- walker.push(ref.target_id)
- end
-
- commits = []
- walker.each do |commit|
- break if commit.author[:time].to_date < from_date
- commits.push(commit)
- end
-
- commits
- end
-
AUTOCRLF_VALUES = {
"true" => true,
"false" => false,
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
index f7450e8b58f..b722d8a9f56 100644
--- a/lib/gitlab/git/tree.rb
+++ b/lib/gitlab/git/tree.rb
@@ -33,7 +33,7 @@ module Gitlab
root_id: root_tree.oid,
name: entry[:name],
type: entry[:type],
- mode: entry[:filemode],
+ mode: entry[:filemode].to_s(8),
path: path ? File.join(path, entry[:name]) : entry[:name],
commit_id: sha,
)
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 1ce47ef2b05..a0dbe0a8c11 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -4,28 +4,30 @@ 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}"
- end
+ def self.configure_channel(storage, address)
+ @addresses ||= {}
+ @addresses[storage] = address
+ @channels ||= {}
+ @channels[storage] = new_channel(address)
+ 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
- def self.channel
- return @channel if defined?(@channel)
+ def self.get_channel(storage)
+ @channels[storage]
+ end
- @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
+ def self.get_address(storage)
+ @addresses[storage]
end
def self.enabled?
- gitaly_address.present?
+ Gitlab.config.gitaly.enabled
end
def self.feature_enabled?(feature)
diff --git a/lib/gitlab/gitaly_client/commit.rb b/lib/gitlab/gitaly_client/commit.rb
index 525b8d680e9..f15faebe27e 100644
--- a/lib/gitlab/gitaly_client/commit.rb
+++ b/lib/gitlab/gitaly_client/commit.rb
@@ -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(
@@ -19,6 +21,20 @@ module Gitlab
Gitlab::Git::DiffCollection.new(stub.commit_diff(request), options)
end
+
+ def is_ancestor(repository, ancestor_id, child_id)
+ project = Project.find_by_path(repository.path)
+ channel = GitalyClient.get_channel(project.repository_storage)
+ stub = Gitaly::Commit::Stub.new(nil, nil, channel_override: channel)
+ repo = Gitaly::Repository.new(path: repository.path_to_repo)
+ request = Gitaly::CommitIsAncestorRequest.new(
+ repository: repo,
+ ancestor_id: ancestor_id,
+ child_id: child_id
+ )
+
+ stub.commit_is_ancestor(request).value
+ end
end
end
end
diff --git a/lib/gitlab/gitaly_client/notifications.rb b/lib/gitlab/gitaly_client/notifications.rb
index b827a56207f..cbfb129c002 100644
--- a/lib/gitlab/gitaly_client/notifications.rb
+++ b/lib/gitlab/gitaly_client/notifications.rb
@@ -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
diff --git a/lib/gitlab/github_import/branch_formatter.rb b/lib/gitlab/github_import/branch_formatter.rb
index 5d29e698b27..8aa885fb811 100644
--- a/lib/gitlab/github_import/branch_formatter.rb
+++ b/lib/gitlab/github_import/branch_formatter.rb
@@ -11,6 +11,14 @@ module Gitlab
sha.present? && ref.present?
end
+ def user
+ raw_data.user&.login || 'unknown'
+ end
+
+ def short_sha
+ Commit.truncate_sha(sha)
+ end
+
private
def branch_exists?
diff --git a/lib/gitlab/github_import/pull_request_formatter.rb b/lib/gitlab/github_import/pull_request_formatter.rb
index add7236e339..38660a7ccca 100644
--- a/lib/gitlab/github_import/pull_request_formatter.rb
+++ b/lib/gitlab/github_import/pull_request_formatter.rb
@@ -1,8 +1,8 @@
module Gitlab
module GithubImport
class PullRequestFormatter < IssuableFormatter
- delegate :exists?, :project, :ref, :repo, :sha, to: :source_branch, prefix: true
- delegate :exists?, :project, :ref, :repo, :sha, to: :target_branch, prefix: true
+ delegate :user, :project, :ref, :repo, :sha, to: :source_branch, prefix: true
+ delegate :user, :exists?, :project, :ref, :repo, :sha, :short_sha, to: :target_branch, prefix: true
def attributes
{
@@ -37,13 +37,20 @@ module Gitlab
end
def source_branch_name
- @source_branch_name ||= begin
- if cross_project?
- "pull/#{number}/#{source_branch_repo.full_name}/#{source_branch_ref}"
+ @source_branch_name ||=
+ if cross_project? || !source_branch_exists?
+ source_branch_name_prefixed
else
- source_branch_exists? ? source_branch_ref : "pull/#{number}/#{source_branch_ref}"
+ source_branch_ref
end
- end
+ end
+
+ def source_branch_name_prefixed
+ "gh-#{target_branch_short_sha}/#{number}/#{source_branch_user}/#{source_branch_ref}"
+ end
+
+ def source_branch_exists?
+ !cross_project? && source_branch.exists?
end
def target_branch
@@ -51,13 +58,17 @@ module Gitlab
end
def target_branch_name
- @target_branch_name ||= begin
- target_branch_exists? ? target_branch_ref : "pull/#{number}/#{target_branch_ref}"
- end
+ @target_branch_name ||= target_branch_exists? ? target_branch_ref : target_branch_name_prefixed
+ end
+
+ def target_branch_name_prefixed
+ "gl-#{target_branch_short_sha}/#{number}/#{target_branch_user}/#{target_branch_ref}"
end
def cross_project?
- source_branch.repo.id != target_branch.repo.id
+ return true if source_branch_repo.nil?
+
+ source_branch_repo.id != target_branch_repo.id
end
def opened?
diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb
index 28129198438..46deea3cc9f 100644
--- a/lib/gitlab/ldap/config.rb
+++ b/lib/gitlab/ldap/config.rb
@@ -124,9 +124,9 @@ module Gitlab
def name_proc
if allow_username_or_email_login
- Proc.new { |name| name.gsub(/@.*\z/, '') }
+ proc { |name| name.gsub(/@.*\z/, '') }
else
- Proc.new { |name| name }
+ proc { |name| name }
end
end
diff --git a/lib/gitlab/polling_interval.rb b/lib/gitlab/polling_interval.rb
new file mode 100644
index 00000000000..c44bb1cd14d
--- /dev/null
+++ b/lib/gitlab/polling_interval.rb
@@ -0,0 +1,22 @@
+module Gitlab
+ class PollingInterval
+ include Gitlab::CurrentSettings
+
+ HEADER_NAME = 'Poll-Interval'.freeze
+
+ def self.set_header(response, interval:)
+ if polling_enabled?
+ multiplier = current_application_settings.polling_interval_multiplier
+ value = (interval * multiplier).to_i
+ else
+ value = -1
+ end
+
+ response.headers[HEADER_NAME] = value
+ end
+
+ def self.polling_enabled?
+ !current_application_settings.polling_interval_multiplier.zero?
+ end
+ end
+end
diff --git a/lib/gitlab/repo_path.rb b/lib/gitlab/repo_path.rb
new file mode 100644
index 00000000000..4b1d828c45c
--- /dev/null
+++ b/lib/gitlab/repo_path.rb
@@ -0,0 +1,23 @@
+module Gitlab
+ module RepoPath
+ NotFoundError = Class.new(StandardError)
+
+ def self.strip_storage_path(repo_path)
+ result = nil
+
+ Gitlab.config.repositories.storages.values.each do |params|
+ storage_path = params['path']
+ if repo_path.start_with?(storage_path)
+ result = repo_path.sub(storage_path, '')
+ break
+ end
+ end
+
+ if result.nil?
+ raise NotFoundError.new("No known storage path matches #{repo_path.inspect}")
+ end
+
+ result.sub(/\A\/*/, '')
+ end
+ end
+end
diff --git a/lib/gitlab/uploads_transfer.rb b/lib/gitlab/uploads_transfer.rb
index 81701831a6a..7d0c47c5361 100644
--- a/lib/gitlab/uploads_transfer.rb
+++ b/lib/gitlab/uploads_transfer.rb
@@ -1,7 +1,7 @@
module Gitlab
class UploadsTransfer < ProjectTransfer
def root_dir
- File.join(Rails.root, "public", "uploads")
+ File.join(CarrierWave.root, GitlabUploader.base_dir)
end
end
end
diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb
index eae1a0abf06..d1131ad65e0 100644
--- a/lib/gitlab/workhorse.rb
+++ b/lib/gitlab/workhorse.rb
@@ -1,6 +1,7 @@
require 'base64'
require 'json'
require 'securerandom'
+require 'uri'
module Gitlab
class Workhorse
@@ -16,15 +17,23 @@ module Gitlab
class << self
def git_http_ok(repository, user)
+ repo_path = repository.path_to_repo
params = {
GL_ID: Gitlab::GlId.gl_id(user),
- RepoPath: repository.path_to_repo,
+ RepoPath: repo_path,
}
- params.merge!(
- GitalySocketPath: Gitlab.config.gitaly.socket_path,
- GitalyResourcePath: "/projects/#{repository.project.id}/git-http/info-refs",
- ) if Gitlab.config.gitaly.socket_path.present?
+ if Gitlab.config.gitaly.enabled
+ storage = repository.project.repository_storage
+ address = Gitlab::GitalyClient.get_address(storage)
+ params[:GitalySocketPath] = URI(address).path
+ # TODO: use GitalyClient code to assemble the Repository message
+ params[:Repository] = Gitaly::Repository.new(
+ path: repo_path,
+ storage_name: storage,
+ relative_path: Gitlab::RepoPath.strip_storage_path(repo_path),
+ ).to_h
+ end
params
end
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index a6f8c4ced5d..a9a48f7188f 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -617,7 +617,7 @@ namespace :gitlab do
end
def sidekiq_process_count
- ps_ux, _ = Gitlab::Popen.popen(%w(ps ux))
+ ps_ux, _ = Gitlab::Popen.popen(%w(ps uxww))
ps_ux.scan(/sidekiq \d+\.\d+\.\d+/).count
end
end
@@ -751,7 +751,7 @@ namespace :gitlab do
end
def mail_room_running?
- ps_ux, _ = Gitlab::Popen.popen(%w(ps ux))
+ ps_ux, _ = Gitlab::Popen.popen(%w(ps uxww))
ps_ux.include?("mail_room")
end
end
diff --git a/lib/tasks/karma.rake b/lib/tasks/karma.rake
index 40465ea3bf0..62a12174efa 100644
--- a/lib/tasks/karma.rake
+++ b/lib/tasks/karma.rake
@@ -1,9 +1,10 @@
unless Rails.env.production?
namespace :karma do
desc 'GitLab | Karma | Generate fixtures for JavaScript tests'
- RSpec::Core::RakeTask.new(:fixtures) do |t|
+ RSpec::Core::RakeTask.new(:fixtures, [:pattern]) do |t, args|
+ args.with_defaults(pattern: 'spec/javascripts/fixtures/*.rb')
ENV['NO_KNAPSACK'] = 'true'
- t.pattern = 'spec/javascripts/fixtures/*.rb'
+ t.pattern = args[:pattern]
t.rspec_opts = '--format documentation'
end