Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/api/deploy_keys.rb21
-rw-r--r--lib/api/entities.rb4
-rw-r--r--lib/api/files.rb2
-rw-r--r--lib/api/groups.rb4
-rw-r--r--lib/api/project_snippets.rb2
-rw-r--r--lib/api/settings.rb1
-rw-r--r--lib/api/snippets.rb2
-rw-r--r--lib/api/users.rb4
-rw-r--r--lib/api/v3/files.rb2
-rw-r--r--lib/backup/repository.rb75
-rw-r--r--lib/ci/gitlab_ci_yaml_processor.rb65
-rw-r--r--lib/gitlab/auth.rb35
-rw-r--r--lib/gitlab/auth/result.rb4
-rw-r--r--lib/gitlab/blame.rb2
-rw-r--r--lib/gitlab/ci/stage/seed.rb49
-rw-r--r--lib/gitlab/ci/status/canceled.rb4
-rw-r--r--lib/gitlab/ci/status/created.rb4
-rw-r--r--lib/gitlab/ci/status/failed.rb4
-rw-r--r--lib/gitlab/ci/status/manual.rb4
-rw-r--r--lib/gitlab/ci/status/pending.rb4
-rw-r--r--lib/gitlab/ci/status/pipeline/blocked.rb4
-rw-r--r--lib/gitlab/ci/status/running.rb4
-rw-r--r--lib/gitlab/ci/status/skipped.rb4
-rw-r--r--lib/gitlab/ci/status/success.rb4
-rw-r--r--lib/gitlab/ci/status/success_warning.rb4
-rw-r--r--lib/gitlab/contributions_calendar.rb2
-rw-r--r--lib/gitlab/data_builder/pipeline.rb2
-rw-r--r--lib/gitlab/diff/diff_refs.rb10
-rw-r--r--lib/gitlab/diff/position.rb18
-rw-r--r--lib/gitlab/diff/position_tracer.rb2
-rw-r--r--lib/gitlab/etag_caching/middleware.rb9
-rw-r--r--lib/gitlab/etag_caching/router.rb4
-rw-r--r--lib/gitlab/git/compare.rb2
-rw-r--r--lib/gitlab/health_checks/prometheus_text_format.rb40
-rw-r--r--lib/gitlab/highlight.rb2
-rw-r--r--lib/gitlab/import_export/import_export.yml1
-rw-r--r--lib/gitlab/import_export/relation_factory.rb1
-rw-r--r--lib/gitlab/ldap/user.rb13
-rw-r--r--lib/gitlab/metrics.rb157
-rw-r--r--lib/gitlab/metrics/influx_db.rb170
-rw-r--r--lib/gitlab/metrics/null_metric.rb10
-rw-r--r--lib/gitlab/metrics/prometheus.rb41
-rw-r--r--lib/gitlab/o_auth/user.rb17
-rw-r--r--lib/gitlab/slash_commands/command_definition.rb10
-rw-r--r--lib/gitlab/slash_commands/dsl.rb4
-rw-r--r--lib/gitlab/url_builder.rb7
-rw-r--r--lib/gitlab/visibility_level.rb6
-rw-r--r--lib/rouge/lexers/math.rb16
-rw-r--r--lib/rouge/lexers/plantuml.rb16
49 files changed, 548 insertions, 324 deletions
diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb
index 8a54f7f3f05..7cdee8aced7 100644
--- a/lib/api/deploy_keys.rb
+++ b/lib/api/deploy_keys.rb
@@ -76,6 +76,27 @@ module API
end
end
+ desc 'Update an existing deploy key for a project' do
+ success Entities::SSHKey
+ end
+ params do
+ requires :key_id, type: Integer, desc: 'The ID of the deploy key'
+ optional :title, type: String, desc: 'The name of the deploy key'
+ optional :can_push, type: Boolean, desc: "Can deploy key push to the project's repository"
+ at_least_one_of :title, :can_push
+ end
+ put ":id/deploy_keys/:key_id" do
+ key = user_project.deploy_keys.find(params.delete(:key_id))
+
+ authorize!(:update_deploy_key, key)
+
+ if key.update_attributes(declared_params(include_missing: false))
+ present key, with: Entities::SSHKey
+ else
+ render_validation_error!(key)
+ end
+ end
+
desc 'Enable a deploy key for a project' do
detail 'This feature was added in GitLab 8.11'
success Entities::SSHKey
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index ded5c65e303..a836df3dc81 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -226,7 +226,7 @@ module API
end
class ProjectSnippet < Grape::Entity
- expose :id, :title, :file_name
+ expose :id, :title, :file_name, :description
expose :author, using: Entities::UserBasic
expose :updated_at, :created_at
@@ -236,7 +236,7 @@ module API
end
class PersonalSnippet < Grape::Entity
- expose :id, :title, :file_name
+ expose :id, :title, :file_name, :description
expose :author, using: Entities::UserBasic
expose :updated_at, :created_at
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 25b0968a271..521287ee2b4 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -25,7 +25,7 @@ module API
@blob = @repo.blob_at(@commit.sha, params[:file_path])
not_found!('File') unless @blob
- @blob.load_all_data!(@repo)
+ @blob.load_all_data!
end
def commit_response(attrs)
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index e14a988a153..ebbaed0cbb7 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -83,7 +83,7 @@ module API
group = ::Groups::CreateService.new(current_user, declared_params(include_missing: false)).execute
if group.persisted?
- present group, with: Entities::Group, current_user: current_user
+ present group, with: Entities::GroupDetail, current_user: current_user
else
render_api_error!("Failed to save group #{group.errors.messages}", 400)
end
@@ -101,8 +101,6 @@ module API
optional :name, type: String, desc: 'The name of the group'
optional :path, type: String, desc: 'The path of the group'
use :optional_params
- at_least_one_of :name, :path, :description, :visibility,
- :lfs_enabled, :request_access_enabled
end
put ':id' do
group = find_group!(params[:id])
diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb
index 98bc9c28527..64efe82a937 100644
--- a/lib/api/project_snippets.rb
+++ b/lib/api/project_snippets.rb
@@ -49,6 +49,7 @@ module API
requires :title, type: String, desc: 'The title of the snippet'
requires :file_name, type: String, desc: 'The file name of the snippet'
requires :code, type: String, desc: 'The content of the snippet'
+ optional :description, type: String, desc: 'The description of a snippet'
requires :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
desc: 'The visibility of the snippet'
@@ -77,6 +78,7 @@ module API
optional :title, type: String, desc: 'The title of the snippet'
optional :file_name, type: String, desc: 'The file name of the snippet'
optional :code, type: String, desc: 'The content of the snippet'
+ optional :description, type: String, desc: 'The description of a snippet'
optional :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
desc: 'The visibility of the snippet'
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index 82f513c984e..25027c3b114 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -110,6 +110,7 @@ module API
optional :default_artifacts_expire_in, type: String, desc: "Set the default expiration time for each job's artifacts"
optional :max_pages_size, type: Integer, desc: 'Maximum size of pages in MB'
optional :container_registry_token_expire_delay, type: Integer, desc: 'Authorization token duration (minutes)'
+ optional :prometheus_metrics_enabled, type: Boolean, desc: 'Enable Prometheus metrics'
optional :metrics_enabled, type: Boolean, desc: 'Enable the InfluxDB metrics'
given metrics_enabled: ->(val) { val } do
requires :metrics_host, type: String, desc: 'The InfluxDB host'
diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb
index 53f5953a8fb..c630c24c339 100644
--- a/lib/api/snippets.rb
+++ b/lib/api/snippets.rb
@@ -58,6 +58,7 @@ module API
requires :title, type: String, desc: 'The title of a snippet'
requires :file_name, type: String, desc: 'The name of a snippet file'
requires :content, type: String, desc: 'The content of a snippet'
+ optional :description, type: String, desc: 'The description of a snippet'
optional :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
default: 'internal',
@@ -85,6 +86,7 @@ module API
optional :title, type: String, desc: 'The title of a snippet'
optional :file_name, type: String, desc: 'The name of a snippet file'
optional :content, type: String, desc: 'The content of a snippet'
+ optional :description, type: String, desc: 'The description of a snippet'
optional :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
desc: 'The visibility of the snippet'
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 3f87a403a09..dda64715ee1 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -124,10 +124,6 @@ module API
optional :name, type: String, desc: 'The name of the user'
optional :username, type: String, desc: 'The username of the user'
use :optional_attributes
- at_least_one_of :email, :password, :name, :username, :skype, :linkedin,
- :twitter, :website_url, :organization, :projects_limit,
- :extern_uid, :provider, :bio, :location, :admin,
- :can_create_group, :confirm, :external
end
put ":id" do
authenticated_as_admin!
diff --git a/lib/api/v3/files.rb b/lib/api/v3/files.rb
index c76acc86504..7b4b3448b6d 100644
--- a/lib/api/v3/files.rb
+++ b/lib/api/v3/files.rb
@@ -56,7 +56,7 @@ module API
blob = repo.blob_at(commit.sha, params[:file_path])
not_found!('File') unless blob
- blob.load_all_data!(repo)
+ blob.load_all_data!
status(200)
{
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index 6b29600a751..a1685c77916 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -7,15 +7,15 @@ module Backup
prepare
Project.find_each(batch_size: 1000) do |project|
- $progress.print " * #{project.path_with_namespace} ... "
+ progress.print " * #{project.path_with_namespace} ... "
path_to_project_repo = path_to_repo(project)
path_to_project_bundle = path_to_bundle(project)
# Create namespace dir if missing
FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.full_path)) if project.namespace
- if project.empty_repo?
- $progress.puts "[SKIPPED]".color(:cyan)
+ if empty_repo?(project)
+ progress.puts "[SKIPPED]".color(:cyan)
else
in_path(path_to_project_repo) do |dir|
FileUtils.mkdir_p(path_to_tars(project))
@@ -23,10 +23,7 @@ module Backup
output, status = Gitlab::Popen.popen(cmd)
unless status.zero?
- puts "[FAILED]".color(:red)
- puts "failed: #{cmd.join(' ')}"
- puts output
- abort 'Backup failed'
+ progress_warn(project, cmd.join(' '), output)
end
end
@@ -34,12 +31,9 @@ module Backup
output, status = Gitlab::Popen.popen(cmd)
if status.zero?
- $progress.puts "[DONE]".color(:green)
+ progress.puts "[DONE]".color(:green)
else
- puts "[FAILED]".color(:red)
- puts "failed: #{cmd.join(' ')}"
- puts output
- abort 'Backup failed'
+ progress_warn(project, cmd.join(' '), output)
end
end
@@ -48,19 +42,16 @@ module Backup
path_to_wiki_bundle = path_to_bundle(wiki)
if File.exist?(path_to_wiki_repo)
- $progress.print " * #{wiki.path_with_namespace} ... "
- if wiki.repository.empty?
- $progress.puts " [SKIPPED]".color(:cyan)
+ progress.print " * #{wiki.path_with_namespace} ... "
+ if empty_repo?(wiki)
+ progress.puts " [SKIPPED]".color(:cyan)
else
cmd = %W(#{Gitlab.config.git.bin_path} --git-dir=#{path_to_wiki_repo} bundle create #{path_to_wiki_bundle} --all)
output, status = Gitlab::Popen.popen(cmd)
if status.zero?
- $progress.puts " [DONE]".color(:green)
+ progress.puts " [DONE]".color(:green)
else
- puts " [FAILED]".color(:red)
- puts "failed: #{cmd.join(' ')}"
- puts output
- abort 'Backup failed'
+ progress_warn(wiki, cmd.join(' '), output)
end
end
end
@@ -80,7 +71,7 @@ module Backup
end
Project.find_each(batch_size: 1000) do |project|
- $progress.print " * #{project.path_with_namespace} ... "
+ progress.print " * #{project.path_with_namespace} ... "
path_to_project_repo = path_to_repo(project)
path_to_project_bundle = path_to_bundle(project)
@@ -94,12 +85,9 @@ module Backup
output, status = Gitlab::Popen.popen(cmd)
if status.zero?
- $progress.puts "[DONE]".color(:green)
+ progress.puts "[DONE]".color(:green)
else
- puts "[FAILED]".color(:red)
- puts "failed: #{cmd.join(' ')}"
- puts output
- abort 'Restore failed'
+ progress_warn(project, cmd.join(' '), output)
end
in_path(path_to_tars(project)) do |dir|
@@ -107,10 +95,7 @@ module Backup
output, status = Gitlab::Popen.popen(cmd)
unless status.zero?
- puts "[FAILED]".color(:red)
- puts "failed: #{cmd.join(' ')}"
- puts output
- abort 'Restore failed'
+ progress_warn(project, cmd.join(' '), output)
end
end
@@ -119,7 +104,7 @@ module Backup
path_to_wiki_bundle = path_to_bundle(wiki)
if File.exist?(path_to_wiki_bundle)
- $progress.print " * #{wiki.path_with_namespace} ... "
+ progress.print " * #{wiki.path_with_namespace} ... "
# If a wiki bundle exists, first remove the empty repo
# that was initialized with ProjectWiki.new() and then
@@ -129,22 +114,19 @@ module Backup
output, status = Gitlab::Popen.popen(cmd)
if status.zero?
- $progress.puts " [DONE]".color(:green)
+ progress.puts " [DONE]".color(:green)
else
- puts " [FAILED]".color(:red)
- puts "failed: #{cmd.join(' ')}"
- puts output
- abort 'Restore failed'
+ progress_warn(project, cmd.join(' '), output)
end
end
end
- $progress.print 'Put GitLab hooks in repositories dirs'.color(:yellow)
+ progress.print 'Put GitLab hooks in repositories dirs'.color(:yellow)
cmd = %W(#{Gitlab.config.gitlab_shell.path}/bin/create-hooks) + repository_storage_paths_args
output, status = Gitlab::Popen.popen(cmd)
if status.zero?
- $progress.puts " [DONE]".color(:green)
+ progress.puts " [DONE]".color(:green)
else
puts " [FAILED]".color(:red)
puts "failed: #{cmd}"
@@ -201,8 +183,25 @@ module Backup
private
+ def progress_warn(project, cmd, output)
+ progress.puts "[WARNING] Executing #{cmd}".color(:orange)
+ progress.puts "Ignoring error on #{project.path_with_namespace} - #{output}".color(:orange)
+ end
+
+ def empty_repo?(project_or_wiki)
+ project_or_wiki.repository.empty_repo?
+ rescue => e
+ progress.puts "Ignoring repository error and continuing backing up project: #{project_or_wiki.path_with_namespace} - #{e.message}".color(:orange)
+
+ false
+ end
+
def repository_storage_paths_args
Gitlab.config.repositories.storages.values.map { |rs| rs['path'] }
end
+
+ def progress
+ $progress
+ end
end
end
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index b06474cda7f..56ad2c77c7d 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -20,26 +20,26 @@ module Ci
raise ValidationError, e.message
end
- def jobs_for_ref(ref, tag = false, trigger_request = nil)
+ def jobs_for_ref(ref, tag = false, source = nil)
@jobs.select do |_, job|
- process?(job[:only], job[:except], ref, tag, trigger_request)
+ process?(job[:only], job[:except], ref, tag, source)
end
end
- def jobs_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil)
- jobs_for_ref(ref, tag, trigger_request).select do |_, job|
+ def jobs_for_stage_and_ref(stage, ref, tag = false, source = nil)
+ jobs_for_ref(ref, tag, source).select do |_, job|
job[:stage] == stage
end
end
- def builds_for_ref(ref, tag = false, trigger_request = nil)
- jobs_for_ref(ref, tag, trigger_request).map do |name, _|
+ def builds_for_ref(ref, tag = false, source = nil)
+ jobs_for_ref(ref, tag, source).map do |name, _|
build_attributes(name)
end
end
- def builds_for_stage_and_ref(stage, ref, tag = false, trigger_request = nil)
- jobs_for_stage_and_ref(stage, ref, tag, trigger_request).map do |name, _|
+ def builds_for_stage_and_ref(stage, ref, tag = false, source = nil)
+ jobs_for_stage_and_ref(stage, ref, tag, source).map do |name, _|
build_attributes(name)
end
end
@@ -50,10 +50,21 @@ module Ci
end
end
+ def stage_seeds(pipeline)
+ seeds = @stages.uniq.map do |stage|
+ builds = builds_for_stage_and_ref(
+ stage, pipeline.ref, pipeline.tag?, pipeline.source)
+
+ Gitlab::Ci::Stage::Seed.new(pipeline, stage, builds) if builds.any?
+ end
+
+ seeds.compact
+ end
+
def build_attributes(name)
job = @jobs[name.to_sym] || {}
- {
- stage_idx: @stages.index(job[:stage]),
+
+ { stage_idx: @stages.index(job[:stage]),
stage: job[:stage],
commands: job[:commands],
tag_list: job[:tags] || [],
@@ -71,8 +82,7 @@ module Ci
dependencies: job[:dependencies],
after_script: job[:after_script],
environment: job[:environment]
- }.compact
- }
+ }.compact }
end
def self.validation_message(content)
@@ -181,30 +191,35 @@ module Ci
end
end
- def process?(only_params, except_params, ref, tag, trigger_request)
+ def process?(only_params, except_params, ref, tag, source)
if only_params.present?
- return false unless matching?(only_params, ref, tag, trigger_request)
+ return false unless matching?(only_params, ref, tag, source)
end
if except_params.present?
- return false if matching?(except_params, ref, tag, trigger_request)
+ return false if matching?(except_params, ref, tag, source)
end
true
end
- def matching?(patterns, ref, tag, trigger_request)
+ def matching?(patterns, ref, tag, source)
patterns.any? do |pattern|
- match_ref?(pattern, ref, tag, trigger_request)
+ pattern, path = pattern.split('@', 2)
+ matches_path?(path) && matches_pattern?(pattern, ref, tag, source)
end
end
- def match_ref?(pattern, ref, tag, trigger_request)
- pattern, path = pattern.split('@', 2)
- return false if path && path != self.path
+ def matches_path?(path)
+ return true unless path
+
+ path == self.path
+ end
+
+ def matches_pattern?(pattern, ref, tag, source)
return true if tag && pattern == 'tags'
return true if !tag && pattern == 'branches'
- return true if trigger_request.present? && pattern == 'triggers'
+ return true if source_to_pattern(source) == pattern
if pattern.first == "/" && pattern.last == "/"
Regexp.new(pattern[1...-1]) =~ ref
@@ -212,5 +227,13 @@ module Ci
pattern == ref
end
end
+
+ def source_to_pattern(source)
+ if %w[api external web].include?(source)
+ source
+ else
+ source&.pluralize
+ end
+ end
end
end
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 099c45dcfb7..da07ba2f2a3 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -2,6 +2,8 @@ module Gitlab
module Auth
MissingPersonalTokenError = Class.new(StandardError)
+ REGISTRY_SCOPES = [:read_registry].freeze
+
# Scopes used for GitLab API access
API_SCOPES = [:api, :read_user].freeze
@@ -11,8 +13,10 @@ module Gitlab
# Default scopes for OAuth applications that don't define their own
DEFAULT_SCOPES = [:api].freeze
+ AVAILABLE_SCOPES = (API_SCOPES + REGISTRY_SCOPES).freeze
+
# Other available scopes
- OPTIONAL_SCOPES = (API_SCOPES + OPENID_SCOPES - DEFAULT_SCOPES).freeze
+ OPTIONAL_SCOPES = (AVAILABLE_SCOPES + OPENID_SCOPES - DEFAULT_SCOPES).freeze
class << self
def find_for_git_client(login, password, project:, ip:)
@@ -26,8 +30,8 @@ module Gitlab
build_access_token_check(login, password) ||
lfs_token_check(login, password) ||
oauth_access_token_check(login, password) ||
- user_with_password_for_git(login, password) ||
personal_access_token_check(password) ||
+ user_with_password_for_git(login, password) ||
Gitlab::Auth::Result.new
rate_limit!(ip, success: result.success?, login: login)
@@ -109,6 +113,7 @@ module Gitlab
def oauth_access_token_check(login, password)
if login == "oauth2" && password.present?
token = Doorkeeper::AccessToken.by_token(password)
+
if valid_oauth_token?(token)
user = User.find_by(id: token.resource_owner_id)
Gitlab::Auth::Result.new(user, nil, :oauth, full_authentication_abilities)
@@ -121,17 +126,23 @@ module Gitlab
token = PersonalAccessTokensFinder.new(state: 'active').find_by(token: password)
- if token && valid_api_token?(token)
- Gitlab::Auth::Result.new(token.user, nil, :personal_token, full_authentication_abilities)
+ if token && valid_scoped_token?(token, AVAILABLE_SCOPES.map(&:to_s))
+ Gitlab::Auth::Result.new(token.user, nil, :personal_token, abilities_for_scope(token.scopes))
end
end
def valid_oauth_token?(token)
- token && token.accessible? && valid_api_token?(token)
+ token && token.accessible? && valid_scoped_token?(token, ["api"])
end
- def valid_api_token?(token)
- AccessTokenValidationService.new(token).include_any_scope?(['api'])
+ def valid_scoped_token?(token, scopes)
+ AccessTokenValidationService.new(token).include_any_scope?(scopes)
+ end
+
+ def abilities_for_scope(scopes)
+ scopes.map do |scope|
+ self.public_send(:"#{scope}_scope_authentication_abilities")
+ end.flatten.uniq
end
def lfs_token_check(login, password)
@@ -202,6 +213,16 @@ module Gitlab
:create_container_image
]
end
+ alias_method :api_scope_authentication_abilities, :full_authentication_abilities
+
+ def read_registry_scope_authentication_abilities
+ [:read_container_image]
+ end
+
+ # The currently used auth method doesn't allow any actions for this scope
+ def read_user_scope_authentication_abilities
+ []
+ end
end
end
end
diff --git a/lib/gitlab/auth/result.rb b/lib/gitlab/auth/result.rb
index 39b86c61a18..75451cf8aa9 100644
--- a/lib/gitlab/auth/result.rb
+++ b/lib/gitlab/auth/result.rb
@@ -15,6 +15,10 @@ module Gitlab
def success?
actor.present? || type == :ci
end
+
+ def failed?
+ !success?
+ end
end
end
end
diff --git a/lib/gitlab/blame.rb b/lib/gitlab/blame.rb
index d62bc50ce78..169aac79854 100644
--- a/lib/gitlab/blame.rb
+++ b/lib/gitlab/blame.rb
@@ -40,7 +40,7 @@ module Gitlab
end
def highlighted_lines
- @blob.load_all_data!(repository)
+ @blob.load_all_data!
@highlighted_lines ||=
Gitlab::Highlight.highlight(@blob.path, @blob.data, repository: repository).lines
end
diff --git a/lib/gitlab/ci/stage/seed.rb b/lib/gitlab/ci/stage/seed.rb
new file mode 100644
index 00000000000..f81f9347b4d
--- /dev/null
+++ b/lib/gitlab/ci/stage/seed.rb
@@ -0,0 +1,49 @@
+module Gitlab
+ module Ci
+ module Stage
+ class Seed
+ attr_reader :pipeline
+ delegate :project, to: :pipeline
+
+ def initialize(pipeline, stage, jobs)
+ @pipeline = pipeline
+ @stage = { name: stage }
+ @jobs = jobs.to_a.dup
+ end
+
+ def user=(current_user)
+ @jobs.map! do |attributes|
+ attributes.merge(user: current_user)
+ end
+ end
+
+ def stage
+ @stage.merge(project: project)
+ end
+
+ def builds
+ trigger = pipeline.trigger_requests.first
+
+ @jobs.map do |attributes|
+ attributes.merge(project: project,
+ ref: pipeline.ref,
+ tag: pipeline.tag,
+ trigger_request: trigger)
+ end
+ end
+
+ def create!
+ pipeline.stages.create!(stage).tap do |stage|
+ builds_attributes = builds.map do |attributes|
+ attributes.merge(stage_id: stage.id)
+ end
+
+ pipeline.builds.create!(builds_attributes).each do |build|
+ yield build if block_given?
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/status/canceled.rb b/lib/gitlab/ci/status/canceled.rb
index 97c121ce7b9..e5fdc1f8136 100644
--- a/lib/gitlab/ci/status/canceled.rb
+++ b/lib/gitlab/ci/status/canceled.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Canceled < Status::Core
def text
- 'canceled'
+ s_('CiStatusText|canceled')
end
def label
- 'canceled'
+ s_('CiStatusLabel|canceled')
end
def icon
diff --git a/lib/gitlab/ci/status/created.rb b/lib/gitlab/ci/status/created.rb
index 0721bf6ec7c..d188bd286a6 100644
--- a/lib/gitlab/ci/status/created.rb
+++ b/lib/gitlab/ci/status/created.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Created < Status::Core
def text
- 'created'
+ s_('CiStatusText|created')
end
def label
- 'created'
+ s_('CiStatusLabel|created')
end
def icon
diff --git a/lib/gitlab/ci/status/failed.rb b/lib/gitlab/ci/status/failed.rb
index cb75e9383a8..38e45714c22 100644
--- a/lib/gitlab/ci/status/failed.rb
+++ b/lib/gitlab/ci/status/failed.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Failed < Status::Core
def text
- 'failed'
+ s_('CiStatusText|failed')
end
def label
- 'failed'
+ s_('CiStatusLabel|failed')
end
def icon
diff --git a/lib/gitlab/ci/status/manual.rb b/lib/gitlab/ci/status/manual.rb
index f8f6c2903ba..a4a7edadac9 100644
--- a/lib/gitlab/ci/status/manual.rb
+++ b/lib/gitlab/ci/status/manual.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Manual < Status::Core
def text
- 'manual'
+ s_('CiStatusText|manual')
end
def label
- 'manual action'
+ s_('CiStatusLabel|manual action')
end
def icon
diff --git a/lib/gitlab/ci/status/pending.rb b/lib/gitlab/ci/status/pending.rb
index f40cc1314dc..5164260b861 100644
--- a/lib/gitlab/ci/status/pending.rb
+++ b/lib/gitlab/ci/status/pending.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Pending < Status::Core
def text
- 'pending'
+ s_('CiStatusText|pending')
end
def label
- 'pending'
+ s_('CiStatusLabel|pending')
end
def icon
diff --git a/lib/gitlab/ci/status/pipeline/blocked.rb b/lib/gitlab/ci/status/pipeline/blocked.rb
index 37dfe43fb62..bf7e484ee9b 100644
--- a/lib/gitlab/ci/status/pipeline/blocked.rb
+++ b/lib/gitlab/ci/status/pipeline/blocked.rb
@@ -4,11 +4,11 @@ module Gitlab
module Pipeline
class Blocked < Status::Extended
def text
- 'blocked'
+ s_('CiStatusText|blocked')
end
def label
- 'waiting for manual action'
+ s_('CiStatusLabel|waiting for manual action')
end
def self.matches?(pipeline, user)
diff --git a/lib/gitlab/ci/status/running.rb b/lib/gitlab/ci/status/running.rb
index 1237cd47dc8..993937e98ca 100644
--- a/lib/gitlab/ci/status/running.rb
+++ b/lib/gitlab/ci/status/running.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Running < Status::Core
def text
- 'running'
+ s_('CiStatus|running')
end
def label
- 'running'
+ s_('CiStatus|running')
end
def icon
diff --git a/lib/gitlab/ci/status/skipped.rb b/lib/gitlab/ci/status/skipped.rb
index 28005d91503..0c942920b02 100644
--- a/lib/gitlab/ci/status/skipped.rb
+++ b/lib/gitlab/ci/status/skipped.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Skipped < Status::Core
def text
- 'skipped'
+ s_('CiStatusText|skipped')
end
def label
- 'skipped'
+ s_('CiStatusLabel|skipped')
end
def icon
diff --git a/lib/gitlab/ci/status/success.rb b/lib/gitlab/ci/status/success.rb
index 88f7758a270..d7af98857b0 100644
--- a/lib/gitlab/ci/status/success.rb
+++ b/lib/gitlab/ci/status/success.rb
@@ -3,11 +3,11 @@ module Gitlab
module Status
class Success < Status::Core
def text
- 'passed'
+ s_('CiStatusText|passed')
end
def label
- 'passed'
+ s_('CiStatusLabel|passed')
end
def icon
diff --git a/lib/gitlab/ci/status/success_warning.rb b/lib/gitlab/ci/status/success_warning.rb
index df6e76b0151..4d7d82e04cf 100644
--- a/lib/gitlab/ci/status/success_warning.rb
+++ b/lib/gitlab/ci/status/success_warning.rb
@@ -7,11 +7,11 @@ module Gitlab
#
class SuccessWarning < Status::Extended
def text
- 'passed'
+ s_('CiStatusText|passed')
end
def label
- 'passed with warnings'
+ s_('CiStatusLabel|passed with warnings')
end
def icon
diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb
index 15992b77680..060e013183f 100644
--- a/lib/gitlab/contributions_calendar.rb
+++ b/lib/gitlab/contributions_calendar.rb
@@ -28,7 +28,7 @@ module Gitlab
union = Gitlab::SQL::Union.new([repo_events, issue_events, mr_events, note_events])
events = Event.find_by_sql(union.to_sql).map(&:attributes)
- @activity_events = events.each_with_object(Hash.new {|h, k| h[k] = 0 }) do |event, activities|
+ @activity_dates = events.each_with_object(Hash.new {|h, k| h[k] = 0 }) do |event, activities|
activities[event["date"]] += event["total_amount"]
end
end
diff --git a/lib/gitlab/data_builder/pipeline.rb b/lib/gitlab/data_builder/pipeline.rb
index 182a30fd74d..e47fb85b5ee 100644
--- a/lib/gitlab/data_builder/pipeline.rb
+++ b/lib/gitlab/data_builder/pipeline.rb
@@ -22,7 +22,7 @@ module Gitlab
sha: pipeline.sha,
before_sha: pipeline.before_sha,
status: pipeline.status,
- stages: pipeline.stages_name,
+ stages: pipeline.stages_names,
created_at: pipeline.created_at,
finished_at: pipeline.finished_at,
duration: pipeline.duration
diff --git a/lib/gitlab/diff/diff_refs.rb b/lib/gitlab/diff/diff_refs.rb
index 7948782aecc..371cbe04b9b 100644
--- a/lib/gitlab/diff/diff_refs.rb
+++ b/lib/gitlab/diff/diff_refs.rb
@@ -37,6 +37,16 @@ module Gitlab
def complete?
start_sha && head_sha
end
+
+ def compare_in(project)
+ # We're at the initial commit, so just get that as we can't compare to anything.
+ if Gitlab::Git.blank_ref?(start_sha)
+ project.commit(head_sha)
+ else
+ straight = start_sha == base_sha
+ CompareService.new(project, head_sha).execute(project, start_sha, straight: straight)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb
index 4d96778a2b2..f80afb20f0c 100644
--- a/lib/gitlab/diff/position.rb
+++ b/lib/gitlab/diff/position.rb
@@ -145,23 +145,9 @@ module Gitlab
private
def find_diff_file(repository)
- # We're at the initial commit, so just get that as we can't compare to anything.
- compare =
- if Gitlab::Git.blank_ref?(start_sha)
- Gitlab::Git::Commit.find(repository.raw_repository, head_sha)
- else
- Gitlab::Git::Compare.new(
- repository.raw_repository,
- start_sha,
- head_sha
- )
- end
-
- diff = compare.diffs(paths: paths).first
-
- return unless diff
+ return unless diff_refs.complete?
- Gitlab::Diff::File.new(diff, repository: repository, diff_refs: diff_refs)
+ diff_refs.compare_in(repository.project).diffs(paths: paths, expanded: true).diff_files.first
end
end
end
diff --git a/lib/gitlab/diff/position_tracer.rb b/lib/gitlab/diff/position_tracer.rb
index dcabb5f7fe5..b68a1636814 100644
--- a/lib/gitlab/diff/position_tracer.rb
+++ b/lib/gitlab/diff/position_tracer.rb
@@ -216,7 +216,7 @@ module Gitlab
def compare(start_sha, head_sha, straight: false)
compare = CompareService.new(project, head_sha).execute(project, start_sha, straight: straight)
- compare.diffs(paths: paths)
+ compare.diffs(paths: paths, expanded: true)
end
def position(diff_file, old_line, new_line)
diff --git a/lib/gitlab/etag_caching/middleware.rb b/lib/gitlab/etag_caching/middleware.rb
index 270d67dd50c..7f884183bb1 100644
--- a/lib/gitlab/etag_caching/middleware.rb
+++ b/lib/gitlab/etag_caching/middleware.rb
@@ -6,12 +6,13 @@ module Gitlab
end
def call(env)
- route = Gitlab::EtagCaching::Router.match(env)
+ request = Rack::Request.new(env)
+ route = Gitlab::EtagCaching::Router.match(request)
return @app.call(env) unless route
track_event(:etag_caching_middleware_used, route)
- etag, cached_value_present = get_etag(env)
+ etag, cached_value_present = get_etag(request)
if_none_match = env['HTTP_IF_NONE_MATCH']
if if_none_match == etag
@@ -27,8 +28,8 @@ module Gitlab
private
- def get_etag(env)
- cache_key = env['PATH_INFO']
+ def get_etag(request)
+ cache_key = request.path
store = Gitlab::EtagCaching::Store.new
current_value = store.get(cache_key)
cached_value_present = current_value.present?
diff --git a/lib/gitlab/etag_caching/router.rb b/lib/gitlab/etag_caching/router.rb
index ca49eda51fb..dccc66b3918 100644
--- a/lib/gitlab/etag_caching/router.rb
+++ b/lib/gitlab/etag_caching/router.rb
@@ -53,8 +53,8 @@ module Gitlab
)
].freeze
- def self.match(env)
- ROUTES.find { |route| route.regexp.match(env['PATH_INFO']) }
+ def self.match(request)
+ ROUTES.find { |route| route.regexp.match(request.path_info) }
end
end
end
diff --git a/lib/gitlab/git/compare.rb b/lib/gitlab/git/compare.rb
index 696a2acd5e3..78e440395a5 100644
--- a/lib/gitlab/git/compare.rb
+++ b/lib/gitlab/git/compare.rb
@@ -3,7 +3,7 @@ module Gitlab
class Compare
attr_reader :head, :base, :straight
- def initialize(repository, base, head, straight = false)
+ def initialize(repository, base, head, straight: false)
@repository = repository
@straight = straight
diff --git a/lib/gitlab/health_checks/prometheus_text_format.rb b/lib/gitlab/health_checks/prometheus_text_format.rb
new file mode 100644
index 00000000000..b3c759b4730
--- /dev/null
+++ b/lib/gitlab/health_checks/prometheus_text_format.rb
@@ -0,0 +1,40 @@
+module Gitlab
+ module HealthChecks
+ class PrometheusTextFormat
+ def marshal(metrics)
+ "#{metrics_with_type_declarations(metrics).join("\n")}\n"
+ end
+
+ private
+
+ def metrics_with_type_declarations(metrics)
+ type_declaration_added = {}
+
+ metrics.flat_map do |metric|
+ metric_lines = []
+
+ unless type_declaration_added.key?(metric.name)
+ type_declaration_added[metric.name] = true
+ metric_lines << metric_type_declaration(metric)
+ end
+
+ metric_lines << metric_text(metric)
+ end
+ end
+
+ def metric_type_declaration(metric)
+ "# TYPE #{metric.name} gauge"
+ end
+
+ def metric_text(metric)
+ labels = metric.labels&.map { |key, value| "#{key}=\"#{value}\"" }&.join(',') || ''
+
+ if labels.empty?
+ "#{metric.name} #{metric.value}"
+ else
+ "#{metric.name}{#{labels}} #{metric.value}"
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb
index 83bc230df3e..23bc2f63c8e 100644
--- a/lib/gitlab/highlight.rb
+++ b/lib/gitlab/highlight.rb
@@ -9,7 +9,7 @@ module Gitlab
blob = repository.blob_at(ref, file_name)
return [] unless blob
- blob.load_all_data!(repository)
+ blob.load_all_data!
highlight(file_name, blob.data, repository: repository).lines.map!(&:html_safe)
end
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index d0f3cf2b514..ff2b1d08c3c 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -38,6 +38,7 @@ project_tree:
- notes:
- :author
- :events
+ - :stages
- :statuses
- :triggers
- :pipeline_schedules
diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb
index 19e23a4715f..695852526cb 100644
--- a/lib/gitlab/import_export/relation_factory.rb
+++ b/lib/gitlab/import_export/relation_factory.rb
@@ -3,6 +3,7 @@ module Gitlab
class RelationFactory
OVERRIDES = { snippets: :project_snippets,
pipelines: 'Ci::Pipeline',
+ stages: 'Ci::Stage',
statuses: 'commit_status',
triggers: 'Ci::Trigger',
pipeline_schedules: 'Ci::PipelineSchedule',
diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb
index 2d5e47a6f3b..5e299e26c54 100644
--- a/lib/gitlab/ldap/user.rb
+++ b/lib/gitlab/ldap/user.rb
@@ -41,11 +41,6 @@ module Gitlab
def update_user_attributes
if persisted?
- if auth_hash.has_email?
- gl_user.skip_reconfirmation!
- gl_user.email = auth_hash.email
- end
-
# find_or_initialize_by doesn't update `gl_user.identities`, and isn't autosaved.
identity = gl_user.identities.find { |identity| identity.provider == auth_hash.provider }
identity ||= gl_user.identities.build(provider: auth_hash.provider)
@@ -55,10 +50,6 @@ module Gitlab
# For an existing identity with no change in DN, this line changes nothing.
identity.extern_uid = auth_hash.uid
end
-
- gl_user.ldap_email = auth_hash.has_email?
-
- gl_user
end
def changed?
@@ -69,6 +60,10 @@ module Gitlab
ldap_config.block_auto_created_users
end
+ def sync_email_from_provider?
+ true
+ end
+
def allowed?
Gitlab::LDAP::Access.allowed?(gl_user)
end
diff --git a/lib/gitlab/metrics.rb b/lib/gitlab/metrics.rb
index cb8db2f1e9f..4779755bb22 100644
--- a/lib/gitlab/metrics.rb
+++ b/lib/gitlab/metrics.rb
@@ -1,161 +1,10 @@
module Gitlab
module Metrics
- extend Gitlab::CurrentSettings
-
- RAILS_ROOT = Rails.root.to_s
- METRICS_ROOT = Rails.root.join('lib', 'gitlab', 'metrics').to_s
- PATH_REGEX = /^#{RAILS_ROOT}\/?/
-
- def self.settings
- @settings ||= {
- enabled: current_application_settings[:metrics_enabled],
- pool_size: current_application_settings[:metrics_pool_size],
- timeout: current_application_settings[:metrics_timeout],
- method_call_threshold: current_application_settings[:metrics_method_call_threshold],
- host: current_application_settings[:metrics_host],
- port: current_application_settings[:metrics_port],
- sample_interval: current_application_settings[:metrics_sample_interval] || 15,
- packet_size: current_application_settings[:metrics_packet_size] || 1
- }
- end
+ extend Gitlab::Metrics::InfluxDb
+ extend Gitlab::Metrics::Prometheus
def self.enabled?
- settings[:enabled] || false
- end
-
- def self.mri?
- RUBY_ENGINE == 'ruby'
- end
-
- def self.method_call_threshold
- # This is memoized since this method is called for every instrumented
- # method. Loading data from an external cache on every method call slows
- # things down too much.
- @method_call_threshold ||= settings[:method_call_threshold]
- end
-
- def self.pool
- @pool
- end
-
- def self.submit_metrics(metrics)
- prepared = prepare_metrics(metrics)
-
- pool.with do |connection|
- prepared.each_slice(settings[:packet_size]) do |slice|
- begin
- connection.write_points(slice)
- rescue StandardError
- end
- end
- end
- rescue Errno::EADDRNOTAVAIL, SocketError => ex
- Gitlab::EnvironmentLogger.error('Cannot resolve InfluxDB address. GitLab Performance Monitoring will not work.')
- Gitlab::EnvironmentLogger.error(ex)
- end
-
- def self.prepare_metrics(metrics)
- metrics.map do |hash|
- new_hash = hash.symbolize_keys
-
- new_hash[:tags].each do |key, value|
- if value.blank?
- new_hash[:tags].delete(key)
- else
- new_hash[:tags][key] = escape_value(value)
- end
- end
-
- new_hash
- end
- end
-
- def self.escape_value(value)
- value.to_s.gsub('=', '\\=')
- end
-
- # Measures the execution time of a block.
- #
- # Example:
- #
- # Gitlab::Metrics.measure(:find_by_username_duration) do
- # User.find_by_username(some_username)
- # end
- #
- # name - The name of the field to store the execution time in.
- #
- # Returns the value yielded by the supplied block.
- def self.measure(name)
- trans = current_transaction
-
- return yield unless trans
-
- real_start = Time.now.to_f
- cpu_start = System.cpu_time
-
- retval = yield
-
- cpu_stop = System.cpu_time
- real_stop = Time.now.to_f
-
- real_time = (real_stop - real_start) * 1000.0
- cpu_time = cpu_stop - cpu_start
-
- trans.increment("#{name}_real_time", real_time)
- trans.increment("#{name}_cpu_time", cpu_time)
- trans.increment("#{name}_call_count", 1)
-
- retval
- end
-
- # Adds a tag to the current transaction (if any)
- #
- # name - The name of the tag to add.
- # value - The value of the tag.
- def self.tag_transaction(name, value)
- trans = current_transaction
-
- trans&.add_tag(name, value)
- end
-
- # Sets the action of the current transaction (if any)
- #
- # action - The name of the action.
- def self.action=(action)
- trans = current_transaction
-
- trans&.action = action
- end
-
- # Tracks an event.
- #
- # See `Gitlab::Metrics::Transaction#add_event` for more details.
- def self.add_event(*args)
- trans = current_transaction
-
- trans&.add_event(*args)
- end
-
- # Returns the prefix to use for the name of a series.
- def self.series_prefix
- @series_prefix ||= Sidekiq.server? ? 'sidekiq_' : 'rails_'
- end
-
- # Allow access from other metrics related middlewares
- def self.current_transaction
- Transaction.current
- end
-
- # When enabled this should be set before being used as the usual pattern
- # "@foo ||= bar" is _not_ thread-safe.
- if enabled?
- @pool = ConnectionPool.new(size: settings[:pool_size], timeout: settings[:timeout]) do
- host = settings[:host]
- port = settings[:port]
-
- InfluxDB::Client.
- new(udp: { host: host, port: port })
- end
+ influx_metrics_enabled? || prometheus_metrics_enabled?
end
end
end
diff --git a/lib/gitlab/metrics/influx_db.rb b/lib/gitlab/metrics/influx_db.rb
new file mode 100644
index 00000000000..3a39791edbf
--- /dev/null
+++ b/lib/gitlab/metrics/influx_db.rb
@@ -0,0 +1,170 @@
+module Gitlab
+ module Metrics
+ module InfluxDb
+ extend Gitlab::CurrentSettings
+ extend self
+
+ MUTEX = Mutex.new
+ private_constant :MUTEX
+
+ def influx_metrics_enabled?
+ settings[:enabled] || false
+ end
+
+ RAILS_ROOT = Rails.root.to_s
+ METRICS_ROOT = Rails.root.join('lib', 'gitlab', 'metrics').to_s
+ PATH_REGEX = /^#{RAILS_ROOT}\/?/
+
+ def settings
+ @settings ||= {
+ enabled: current_application_settings[:metrics_enabled],
+ pool_size: current_application_settings[:metrics_pool_size],
+ timeout: current_application_settings[:metrics_timeout],
+ method_call_threshold: current_application_settings[:metrics_method_call_threshold],
+ host: current_application_settings[:metrics_host],
+ port: current_application_settings[:metrics_port],
+ sample_interval: current_application_settings[:metrics_sample_interval] || 15,
+ packet_size: current_application_settings[:metrics_packet_size] || 1
+ }
+ end
+
+ def mri?
+ RUBY_ENGINE == 'ruby'
+ end
+
+ def method_call_threshold
+ # This is memoized since this method is called for every instrumented
+ # method. Loading data from an external cache on every method call slows
+ # things down too much.
+ @method_call_threshold ||= settings[:method_call_threshold]
+ end
+
+ def submit_metrics(metrics)
+ prepared = prepare_metrics(metrics)
+
+ pool&.with do |connection|
+ prepared.each_slice(settings[:packet_size]) do |slice|
+ begin
+ connection.write_points(slice)
+ rescue StandardError
+ end
+ end
+ end
+ rescue Errno::EADDRNOTAVAIL, SocketError => ex
+ Gitlab::EnvironmentLogger.error('Cannot resolve InfluxDB address. GitLab Performance Monitoring will not work.')
+ Gitlab::EnvironmentLogger.error(ex)
+ end
+
+ def prepare_metrics(metrics)
+ metrics.map do |hash|
+ new_hash = hash.symbolize_keys
+
+ new_hash[:tags].each do |key, value|
+ if value.blank?
+ new_hash[:tags].delete(key)
+ else
+ new_hash[:tags][key] = escape_value(value)
+ end
+ end
+
+ new_hash
+ end
+ end
+
+ def escape_value(value)
+ value.to_s.gsub('=', '\\=')
+ end
+
+ # Measures the execution time of a block.
+ #
+ # Example:
+ #
+ # Gitlab::Metrics.measure(:find_by_username_duration) do
+ # User.find_by_username(some_username)
+ # end
+ #
+ # name - The name of the field to store the execution time in.
+ #
+ # Returns the value yielded by the supplied block.
+ def measure(name)
+ trans = current_transaction
+
+ return yield unless trans
+
+ real_start = Time.now.to_f
+ cpu_start = System.cpu_time
+
+ retval = yield
+
+ cpu_stop = System.cpu_time
+ real_stop = Time.now.to_f
+
+ real_time = (real_stop - real_start) * 1000.0
+ cpu_time = cpu_stop - cpu_start
+
+ trans.increment("#{name}_real_time", real_time)
+ trans.increment("#{name}_cpu_time", cpu_time)
+ trans.increment("#{name}_call_count", 1)
+
+ retval
+ end
+
+ # Adds a tag to the current transaction (if any)
+ #
+ # name - The name of the tag to add.
+ # value - The value of the tag.
+ def tag_transaction(name, value)
+ trans = current_transaction
+
+ trans&.add_tag(name, value)
+ end
+
+ # Sets the action of the current transaction (if any)
+ #
+ # action - The name of the action.
+ def action=(action)
+ trans = current_transaction
+
+ trans&.action = action
+ end
+
+ # Tracks an event.
+ #
+ # See `Gitlab::Metrics::Transaction#add_event` for more details.
+ def add_event(*args)
+ trans = current_transaction
+
+ trans&.add_event(*args)
+ end
+
+ # Returns the prefix to use for the name of a series.
+ def series_prefix
+ @series_prefix ||= Sidekiq.server? ? 'sidekiq_' : 'rails_'
+ end
+
+ # Allow access from other metrics related middlewares
+ def current_transaction
+ Transaction.current
+ end
+
+ # When enabled this should be set before being used as the usual pattern
+ # "@foo ||= bar" is _not_ thread-safe.
+ def pool
+ if influx_metrics_enabled?
+ if @pool.nil?
+ MUTEX.synchronize do
+ @pool ||= ConnectionPool.new(size: settings[:pool_size], timeout: settings[:timeout]) do
+ host = settings[:host]
+ port = settings[:port]
+
+ InfluxDB::Client.
+ new(udp: { host: host, port: port })
+ end
+ end
+ end
+ @pool
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/null_metric.rb b/lib/gitlab/metrics/null_metric.rb
new file mode 100644
index 00000000000..3b5a2907195
--- /dev/null
+++ b/lib/gitlab/metrics/null_metric.rb
@@ -0,0 +1,10 @@
+module Gitlab
+ module Metrics
+ # Mocks ::Prometheus::Client::Metric and all derived metrics
+ class NullMetric
+ def method_missing(name, *args, &block)
+ nil
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/metrics/prometheus.rb b/lib/gitlab/metrics/prometheus.rb
new file mode 100644
index 00000000000..60686509332
--- /dev/null
+++ b/lib/gitlab/metrics/prometheus.rb
@@ -0,0 +1,41 @@
+require 'prometheus/client'
+
+module Gitlab
+ module Metrics
+ module Prometheus
+ include Gitlab::CurrentSettings
+
+ def prometheus_metrics_enabled?
+ @prometheus_metrics_enabled ||= current_application_settings[:prometheus_metrics_enabled] || false
+ end
+
+ def registry
+ @registry ||= ::Prometheus::Client.registry
+ end
+
+ def counter(name, docstring, base_labels = {})
+ provide_metric(name) || registry.counter(name, docstring, base_labels)
+ end
+
+ def summary(name, docstring, base_labels = {})
+ provide_metric(name) || registry.summary(name, docstring, base_labels)
+ end
+
+ def gauge(name, docstring, base_labels = {})
+ provide_metric(name) || registry.gauge(name, docstring, base_labels)
+ end
+
+ def histogram(name, docstring, base_labels = {}, buckets = ::Prometheus::Client::Histogram::DEFAULT_BUCKETS)
+ provide_metric(name) || registry.histogram(name, docstring, base_labels, buckets)
+ end
+
+ def provide_metric(name)
+ if prometheus_metrics_enabled?
+ registry.get(name)
+ else
+ NullMetric.new
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb
index afd24b4dcc5..7307f8c2c87 100644
--- a/lib/gitlab/o_auth/user.rb
+++ b/lib/gitlab/o_auth/user.rb
@@ -12,6 +12,7 @@ module Gitlab
def initialize(auth_hash)
self.auth_hash = auth_hash
+ update_email
end
def persisted?
@@ -174,6 +175,22 @@ module Gitlab
}
end
+ def sync_email_from_provider?
+ auth_hash.provider.to_s == Gitlab.config.omniauth.sync_email_from_provider.to_s
+ end
+
+ def update_email
+ if auth_hash.has_email? && sync_email_from_provider?
+ if persisted?
+ gl_user.skip_reconfirmation!
+ gl_user.email = auth_hash.email
+ end
+
+ gl_user.external_email = true
+ gl_user.email_provider = auth_hash.provider
+ end
+ end
+
def log
Gitlab::AppLogger
end
diff --git a/lib/gitlab/slash_commands/command_definition.rb b/lib/gitlab/slash_commands/command_definition.rb
index 12a385f90fd..caab8856014 100644
--- a/lib/gitlab/slash_commands/command_definition.rb
+++ b/lib/gitlab/slash_commands/command_definition.rb
@@ -48,17 +48,23 @@ module Gitlab
end
def to_h(opts)
+ context = OpenStruct.new(opts)
+
desc = description
if desc.respond_to?(:call)
- context = OpenStruct.new(opts)
desc = context.instance_exec(&desc) rescue ''
end
+ prms = params
+ if prms.respond_to?(:call)
+ prms = Array(context.instance_exec(&prms)) rescue params
+ end
+
{
name: name,
aliases: aliases,
description: desc,
- params: params
+ params: prms
}
end
diff --git a/lib/gitlab/slash_commands/dsl.rb b/lib/gitlab/slash_commands/dsl.rb
index 614bafbe1b2..1b5b4566d81 100644
--- a/lib/gitlab/slash_commands/dsl.rb
+++ b/lib/gitlab/slash_commands/dsl.rb
@@ -40,8 +40,8 @@ module Gitlab
# command :command_key do |arguments|
# # Awesome code block
# end
- def params(*params)
- @params = params
+ def params(*params, &block)
+ @params = block_given? ? block : params
end
# Allows to give an explanation of what the command will do when
diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb
index ccb456bcc94..23af9318d1a 100644
--- a/lib/gitlab/url_builder.rb
+++ b/lib/gitlab/url_builder.rb
@@ -61,7 +61,12 @@ module Gitlab
elsif object.for_snippet?
snippet = Snippet.find(object.noteable_id)
- project_snippet_url(snippet, anchor: dom_id(object))
+
+ if snippet.is_a?(PersonalSnippet)
+ snippet_url(snippet, anchor: dom_id(object))
+ else
+ project_snippet_url(snippet, anchor: dom_id(object))
+ end
end
end
diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb
index 85da4c8660b..2b53798e70f 100644
--- a/lib/gitlab/visibility_level.rb
+++ b/lib/gitlab/visibility_level.rb
@@ -41,9 +41,9 @@ module Gitlab
def options
{
- 'Private' => PRIVATE,
- 'Internal' => INTERNAL,
- 'Public' => PUBLIC
+ N_('VisibilityLevel|Private') => PRIVATE,
+ N_('VisibilityLevel|Internal') => INTERNAL,
+ N_('VisibilityLevel|Public') => PUBLIC
}
end
diff --git a/lib/rouge/lexers/math.rb b/lib/rouge/lexers/math.rb
index 80784adfd76..939b23a3421 100644
--- a/lib/rouge/lexers/math.rb
+++ b/lib/rouge/lexers/math.rb
@@ -1,21 +1,9 @@
module Rouge
module Lexers
- class Math < Lexer
+ class Math < PlainText
title "A passthrough lexer used for LaTeX input"
- desc "A boring lexer that doesn't highlight anything"
-
+ desc "PLEASE REFACTOR - this should be handled by SyntaxHighlightFilter"
tag 'math'
- mimetypes 'text/plain'
-
- default_options token: 'Text'
-
- def token
- @token ||= Token[option :token]
- end
-
- def stream_tokens(string, &b)
- yield self.token, string
- end
end
end
end
diff --git a/lib/rouge/lexers/plantuml.rb b/lib/rouge/lexers/plantuml.rb
index 7d5700b7f6d..63c461764fc 100644
--- a/lib/rouge/lexers/plantuml.rb
+++ b/lib/rouge/lexers/plantuml.rb
@@ -1,21 +1,9 @@
module Rouge
module Lexers
- class Plantuml < Lexer
+ class Plantuml < PlainText
title "A passthrough lexer used for PlantUML input"
- desc "A boring lexer that doesn't highlight anything"
-
+ desc "PLEASE REFACTOR - this should be handled by SyntaxHighlightFilter"
tag 'plantuml'
- mimetypes 'text/plain'
-
- default_options token: 'Text'
-
- def token
- @token ||= Token[option :token]
- end
-
- def stream_tokens(string, &b)
- yield self.token, string
- end
end
end
end