Commit 556c79d6 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent bffcdf9b
...@@ -60,6 +60,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController ...@@ -60,6 +60,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
font font
message message
starts_at starts_at
target_path
)) ))
end end
end end
...@@ -28,7 +28,8 @@ class Admin::IdentitiesController < Admin::ApplicationController ...@@ -28,7 +28,8 @@ class Admin::IdentitiesController < Admin::ApplicationController
def update def update
if @identity.update(identity_params) if @identity.update(identity_params)
RepairLdapBlockedUserService.new(@user).execute ::Users::RepairLdapBlockedService.new(@user).execute
redirect_to admin_user_identities_path(@user), notice: _('User identity was successfully updated.') redirect_to admin_user_identities_path(@user), notice: _('User identity was successfully updated.')
else else
render :edit render :edit
...@@ -37,7 +38,8 @@ class Admin::IdentitiesController < Admin::ApplicationController ...@@ -37,7 +38,8 @@ class Admin::IdentitiesController < Admin::ApplicationController
def destroy def destroy
if @identity.destroy if @identity.destroy
RepairLdapBlockedUserService.new(@user).execute ::Users::RepairLdapBlockedService.new(@user).execute
redirect_to admin_user_identities_path(@user), status: :found, notice: _('User identity was successfully removed.') redirect_to admin_user_identities_path(@user), status: :found, notice: _('User identity was successfully removed.')
else else
redirect_to admin_user_identities_path(@user), status: :found, alert: _('Failed to remove user identity.') redirect_to admin_user_identities_path(@user), status: :found, alert: _('Failed to remove user identity.')
......
# frozen_string_literal: true # frozen_string_literal: true
module BroadcastMessagesHelper module BroadcastMessagesHelper
def current_broadcast_messages
BroadcastMessage.current(request.path)
end
def broadcast_message(message) def broadcast_message(message)
return unless message.present? return unless message.present?
......
...@@ -20,7 +20,7 @@ class BroadcastMessage < ApplicationRecord ...@@ -20,7 +20,7 @@ class BroadcastMessage < ApplicationRecord
after_commit :flush_redis_cache after_commit :flush_redis_cache
def self.current def self.current(current_path = nil)
messages = cache.fetch(CACHE_KEY, as: BroadcastMessage, expires_in: cache_expires_in) do messages = cache.fetch(CACHE_KEY, as: BroadcastMessage, expires_in: cache_expires_in) do
current_and_future_messages current_and_future_messages
end end
...@@ -33,7 +33,7 @@ class BroadcastMessage < ApplicationRecord ...@@ -33,7 +33,7 @@ class BroadcastMessage < ApplicationRecord
# cache so we don't keep running this code all the time. # cache so we don't keep running this code all the time.
cache.expire(CACHE_KEY) if now_or_future.empty? cache.expire(CACHE_KEY) if now_or_future.empty?
now_or_future.select(&:now?) now_or_future.select(&:now?).select { |message| message.matches_current_path(current_path) }
end end
def self.current_and_future_messages def self.current_and_future_messages
...@@ -72,6 +72,12 @@ class BroadcastMessage < ApplicationRecord ...@@ -72,6 +72,12 @@ class BroadcastMessage < ApplicationRecord
now? || future? now? || future?
end end
def matches_current_path(current_path)
return true if current_path.blank? || target_path.blank?
current_path.match(Regexp.escape(target_path).gsub('\\*', '.*'))
end
def flush_redis_cache def flush_redis_cache
self.class.cache.expire(CACHE_KEY) self.class.cache.expire(CACHE_KEY)
end end
......
...@@ -12,15 +12,18 @@ class MergeRequest::Pipelines ...@@ -12,15 +12,18 @@ class MergeRequest::Pipelines
attr_reader :merge_request attr_reader :merge_request
delegate :all_commit_shas, :source_project, :source_branch, to: :merge_request delegate :commit_shas, :source_project, :source_branch, to: :merge_request
def all def all
return Ci::Pipeline.none unless source_project
strong_memoize(:all_pipelines) do strong_memoize(:all_pipelines) do
pipelines = Ci::Pipeline.from_union( next Ci::Pipeline.none unless source_project
[source_pipelines, detached_pipelines, triggered_for_branch],
remove_duplicates: false) pipelines =
if merge_request.persisted?
pipelines_using_cte
else
triggered_for_branch.for_sha(commit_shas)
end
sort(pipelines) sort(pipelines)
end end
...@@ -28,38 +31,55 @@ class MergeRequest::Pipelines ...@@ -28,38 +31,55 @@ class MergeRequest::Pipelines
private private
def triggered_by_merge_request def pipelines_using_cte
source_project.ci_pipelines cte = Gitlab::SQL::CTE.new(:shas, merge_request.all_commits.select(:sha))
.where(source: :merge_request_event, merge_request: merge_request)
source_pipelines_join = cte.table[:sha].eq(Ci::Pipeline.arel_table[:source_sha])
source_pipelines = filter_by(triggered_by_merge_request, cte, source_pipelines_join)
detached_pipelines = filter_by_sha(triggered_by_merge_request, cte)
pipelines_for_branch = filter_by_sha(triggered_for_branch, cte)
Ci::Pipeline.with(cte.to_arel)
.from_union([source_pipelines, detached_pipelines, pipelines_for_branch])
end
def filter_by_sha(pipelines, cte)
hex = Arel::Nodes::SqlLiteral.new("'hex'")
string_sha = Arel::Nodes::NamedFunction.new('encode', [cte.table[:sha], hex])
join_condition = string_sha.eq(Ci::Pipeline.arel_table[:sha])
filter_by(pipelines, cte, join_condition)
end end
def detached_pipelines def filter_by(pipelines, cte, join_condition)
triggered_by_merge_request.for_sha(all_commit_shas) shas_table =
Ci::Pipeline.arel_table
.join(cte.table, Arel::Nodes::InnerJoin)
.on(join_condition)
.join_sources
pipelines.joins(shas_table)
end end
def source_pipelines def triggered_by_merge_request
triggered_by_merge_request.for_source_sha(all_commit_shas) source_project.ci_pipelines
.where(source: :merge_request_event, merge_request: merge_request)
end end
def triggered_for_branch def triggered_for_branch
source_project.ci_pipelines source_project.ci_pipelines
.where(source: branch_pipeline_sources, ref: source_branch, tag: false) .where(source: branch_pipeline_sources, ref: source_branch, tag: false)
.for_sha(all_commit_shas)
end
def sources
::Ci::Pipeline.sources
end end
def branch_pipeline_sources def branch_pipeline_sources
strong_memoize(:branch_pipeline_sources) do strong_memoize(:branch_pipeline_sources) do
sources.reject { |source| source == EVENT }.values Ci::Pipeline.sources.reject { |source| source == EVENT }.values
end end
end end
def sort(pipelines) def sort(pipelines)
sql = 'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC' sql = 'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC'
query = ApplicationRecord.send(:sanitize_sql_array, [sql, sources[:merge_request_event]]) # rubocop:disable GitlabSecurity/PublicSend query = ApplicationRecord.send(:sanitize_sql_array, [sql, Ci::Pipeline.sources[:merge_request_event]]) # rubocop:disable GitlabSecurity/PublicSend
pipelines.order(Arel.sql(query)) pipelines.order(Arel.sql(query))
end end
......
# frozen_string_literal: true
class RepairLdapBlockedUserService
attr_accessor :user
def initialize(user)
@user = user
end
def execute
user.block if ldap_hard_blocked?
end
private
def ldap_hard_blocked?
user.ldap_blocked? && !user.ldap_user?
end
end
# frozen_string_literal: true
module Users
class RepairLdapBlockedService
attr_accessor :user
def initialize(user)
@user = user
end
def execute
user.block if ldap_hard_blocked?
end
private
def ldap_hard_blocked?
user.ldap_blocked? && !user.ldap_user?
end
end
end
...@@ -38,6 +38,13 @@ ...@@ -38,6 +38,13 @@
= f.label :font, "Font Color" = f.label :font, "Font Color"
.col-sm-10 .col-sm-10
= f.color_field :font, class: "form-control text-font-color" = f.color_field :font, class: "form-control text-font-color"
.form-group.row
.col-sm-2.col-form-label
= f.label :target_path, _('Target Path')
.col-sm-10
= f.text_field :target_path, class: "form-control"
.form-text.text-muted
= _('Paths can contain wildcards, like */welcome')
.form-group.row .form-group.row
.col-sm-2.col-form-label .col-sm-2.col-form-label
= f.label :starts_at, _("Starts at (UTC)") = f.label :starts_at, _("Starts at (UTC)")
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
%th Preview %th Preview
%th Starts %th Starts
%th Ends %th Ends
%th Target Path
%th &nbsp; %th &nbsp;
%tbody %tbody
- @broadcast_messages.each do |message| - @broadcast_messages.each do |message|
...@@ -31,6 +32,8 @@ ...@@ -31,6 +32,8 @@
= message.starts_at = message.starts_at
%td %td
= message.ends_at = message.ends_at
%td
= message.target_path
%td %td
= link_to sprite_icon('pencil-square'), edit_admin_broadcast_message_path(message), title: 'Edit', class: 'btn' = link_to sprite_icon('pencil-square'), edit_admin_broadcast_message_path(message), title: 'Edit', class: 'btn'
= link_to sprite_icon('remove'), admin_broadcast_message_path(message), method: :delete, remote: true, title: 'Remove', class: 'js-remove-tr btn btn-danger' = link_to sprite_icon('remove'), admin_broadcast_message_path(message), method: :delete, remote: true, title: 'Remove', class: 'js-remove-tr btn btn-danger'
......
- BroadcastMessage.current&.each do |message| - current_broadcast_messages&.each do |message|
= broadcast_message(message) = broadcast_message(message)
---
title: Optimize query for CI pipelines of merge request
merge_request: 19653
author:
type: performance
---
title: Add path based targeting to broadcast messages
merge_request:
author:
type: added
...@@ -11,15 +11,11 @@ class UsersNameLowerIndex < ActiveRecord::Migration[4.2] ...@@ -11,15 +11,11 @@ class UsersNameLowerIndex < ActiveRecord::Migration[4.2]
disable_ddl_transaction! disable_ddl_transaction!
def up def up
return unless Gitlab::Database.postgresql?
# On GitLab.com this produces an index with a size of roughly 60 MB. # On GitLab.com this produces an index with a size of roughly 60 MB.
execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON users (LOWER(name))" execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON users (LOWER(name))"
end end
def down def down
return unless Gitlab::Database.postgresql?
execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME}" execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME}"
end end
end end
...@@ -18,7 +18,7 @@ class RescheduleCommitsCountForMergeRequestDiff < ActiveRecord::Migration[4.2] ...@@ -18,7 +18,7 @@ class RescheduleCommitsCountForMergeRequestDiff < ActiveRecord::Migration[4.2]
def up def up
say 'Populating the MergeRequestDiff `commits_count` (reschedule)' say 'Populating the MergeRequestDiff `commits_count` (reschedule)'
execute("SET statement_timeout TO '60s'") if Gitlab::Database.postgresql? execute("SET statement_timeout TO '60s'")
MergeRequestDiff.where(commits_count: nil).each_batch(of: BATCH_SIZE) do |relation, index| MergeRequestDiff.where(commits_count: nil).each_batch(of: BATCH_SIZE) do |relation, index|
start_id, end_id = relation.pluck('MIN(id), MAX(id)').first start_id, end_id = relation.pluck('MIN(id), MAX(id)').first
......
...@@ -11,16 +11,12 @@ class ProjectNameLowerIndex < ActiveRecord::Migration[4.2] ...@@ -11,16 +11,12 @@ class ProjectNameLowerIndex < ActiveRecord::Migration[4.2]
disable_ddl_transaction! disable_ddl_transaction!
def up def up
return unless Gitlab::Database.postgresql?
disable_statement_timeout do disable_statement_timeout do
execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON projects (LOWER(name))" execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON projects (LOWER(name))"
end end
end end
def down def down
return unless Gitlab::Database.postgresql?
disable_statement_timeout do disable_statement_timeout do
execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME}" execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME}"
end end
......
...@@ -5,34 +5,20 @@ class AddNotNullConstraintsToProjectAuthorizations < ActiveRecord::Migration[4.2 ...@@ -5,34 +5,20 @@ class AddNotNullConstraintsToProjectAuthorizations < ActiveRecord::Migration[4.2
DOWNTIME = false DOWNTIME = false
def up def up
if Gitlab::Database.postgresql? execute <<~SQL
# One-pass version for PostgreSQL
execute <<~SQL
ALTER TABLE project_authorizations ALTER TABLE project_authorizations
ALTER COLUMN user_id SET NOT NULL, ALTER COLUMN user_id SET NOT NULL,
ALTER COLUMN project_id SET NOT NULL, ALTER COLUMN project_id SET NOT NULL,
ALTER COLUMN access_level SET NOT NULL ALTER COLUMN access_level SET NOT NULL
SQL SQL
else
change_column_null :project_authorizations, :user_id, false
change_column_null :project_authorizations, :project_id, false
change_column_null :project_authorizations, :access_level, false
end
end end
def down def down
if Gitlab::Database.postgresql? execute <<~SQL
# One-pass version for PostgreSQL
execute <<~SQL
ALTER TABLE project_authorizations ALTER TABLE project_authorizations
ALTER COLUMN user_id DROP NOT NULL, ALTER COLUMN user_id DROP NOT NULL,
ALTER COLUMN project_id DROP NOT NULL, ALTER COLUMN project_id DROP NOT NULL,
ALTER COLUMN access_level DROP NOT NULL ALTER COLUMN access_level DROP NOT NULL
SQL SQL
else
change_column_null :project_authorizations, :user_id, true
change_column_null :project_authorizations, :project_id, true
change_column_null :project_authorizations, :access_level, true
end
end end
end end
...@@ -464,15 +464,12 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0] ...@@ -464,15 +464,12 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
end end
def update_environments def update_environments
return unless Gitlab::Database.postgresql?
return if index_exists?(:environments, :name, name: 'index_environments_on_name_varchar_pattern_ops') return if index_exists?(:environments, :name, name: 'index_environments_on_name_varchar_pattern_ops')
execute('CREATE INDEX CONCURRENTLY index_environments_on_name_varchar_pattern_ops ON environments (name varchar_pattern_ops);') execute('CREATE INDEX CONCURRENTLY index_environments_on_name_varchar_pattern_ops ON environments (name varchar_pattern_ops);')
end end
def revert_environments def revert_environments
return unless Gitlab::Database.postgresql?
remove_concurrent_index_by_name( remove_concurrent_index_by_name(
:environments, :environments,
'index_environments_on_name_varchar_pattern_ops' 'index_environments_on_name_varchar_pattern_ops'
......
# frozen_string_literal: true
class AddTargetPathToBroadcastMessage < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
add_column :broadcast_messages, :target_path, :string, limit: 255
end
end
...@@ -27,8 +27,6 @@ class CompositePrimaryKeysMigration < ActiveRecord::Migration[4.2] ...@@ -27,8 +27,6 @@ class CompositePrimaryKeysMigration < ActiveRecord::Migration[4.2]
disable_ddl_transaction! disable_ddl_transaction!
def up def up
return unless Gitlab::Database.postgresql?
disable_statement_timeout do disable_statement_timeout do
TABLES.each do |index| TABLES.each do |index|
add_primary_key(index) add_primary_key(index)
...@@ -37,8 +35,6 @@ class CompositePrimaryKeysMigration < ActiveRecord::Migration[4.2] ...@@ -37,8 +35,6 @@ class CompositePrimaryKeysMigration < ActiveRecord::Migration[4.2]
end end
def down def down
return unless Gitlab::Database.postgresql?
disable_statement_timeout do disable_statement_timeout do
TABLES.each do |index| TABLES.each do |index|
remove_primary_key(index) remove_primary_key(index)
......
...@@ -14,11 +14,9 @@ class RemovePermanentFromRedirectRoutes < ActiveRecord::Migration[4.2] ...@@ -14,11 +14,9 @@ class RemovePermanentFromRedirectRoutes < ActiveRecord::Migration[4.2]
# These indexes were created on Postgres only in: # These indexes were created on Postgres only in:
# ReworkRedirectRoutesIndexes: # ReworkRedirectRoutesIndexes:
# https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/16211 # https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/16211
if Gitlab::Database.postgresql? disable_statement_timeout do
disable_statement_timeout do execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_PERM};"
execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_PERM};" execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_TEMP};"
execute "DROP INDEX CONCURRENTLY IF EXISTS #{INDEX_NAME_TEMP};"
end
end end
remove_column(:redirect_routes, :permanent) remove_column(:redirect_routes, :permanent)
...@@ -27,11 +25,9 @@ class RemovePermanentFromRedirectRoutes < ActiveRecord::Migration[4.2] ...@@ -27,11 +25,9 @@ class RemovePermanentFromRedirectRoutes < ActiveRecord::Migration[4.2]
def down def down
add_column(:redirect_routes, :permanent, :boolean) add_column(:redirect_routes, :permanent, :boolean)
if Gitlab::Database.postgresql? disable_statement_timeout do
disable_statement_timeout do execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME_PERM} ON redirect_routes (lower(path) varchar_pattern_ops) where (permanent);")
execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME_PERM} ON redirect_routes (lower(path) varchar_pattern_ops) where (permanent);") execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME_TEMP} ON redirect_routes (lower(path) varchar_pattern_ops) where (not permanent or permanent is null) ;")
execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME_TEMP} ON redirect_routes (lower(path) varchar_pattern_ops) where (not permanent or permanent is null) ;")
end
end end
end end
end end
...@@ -16,8 +16,6 @@ class AddPathIndexToRedirectRoutes < ActiveRecord::Migration[4.2] ...@@ -16,8 +16,6 @@ class AddPathIndexToRedirectRoutes < ActiveRecord::Migration[4.2]
# This same index is also added in the `ReworkRedirectRoutesIndexes` so this # This same index is also added in the `ReworkRedirectRoutesIndexes` so this
# is a no-op in most cases. # is a no-op in most cases.
def up def up
return unless Gitlab::Database.postgresql?
disable_statement_timeout do disable_statement_timeout do
unless index_exists_by_name?(:redirect_routes, INDEX_NAME) unless index_exists_by_name?(:redirect_routes, INDEX_NAME)
execute("CREATE UNIQUE INDEX CONCURRENTLY #{INDEX_NAME} ON redirect_routes (lower(path) varchar_pattern_ops);") execute("CREATE UNIQUE INDEX CONCURRENTLY #{INDEX_NAME} ON redirect_routes (lower(path) varchar_pattern_ops);")
......
...@@ -7,13 +7,13 @@ class PopulateSiteStatistics < ActiveRecord::Migration[4.2] ...@@ -7,13 +7,13 @@ class PopulateSiteStatistics < ActiveRecord::Migration[4.2]
def up def up
transaction do transaction do
execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967 execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)") execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)")
end end
transaction do transaction do
execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967 execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)") execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)")
end end
......
...@@ -20,7 +20,7 @@ class MigrateNullWikiAccessLevels < ActiveRecord::Migration[4.2] ...@@ -20,7 +20,7 @@ class MigrateNullWikiAccessLevels < ActiveRecord::Migration[4.2]
# We need to re-count wikis as previous attempt was not considering the NULLs. # We need to re-count wikis as previous attempt was not considering the NULLs.
transaction do transaction do
execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967 execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)") execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)")
end end
......
...@@ -9,13 +9,13 @@ class RecalculateSiteStatistics < ActiveRecord::Migration[4.2] ...@@ -9,13 +9,13 @@ class RecalculateSiteStatistics < ActiveRecord::Migration[4.2]
def up def up
transaction do transaction do
execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967 execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)") execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)")
end end
transaction do transaction do
execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967 execute('SET LOCAL statement_timeout TO 0') # see https://gitlab.com/gitlab-org/gitlab-foss/issues/48967
execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)") execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)")
end end
......
...@@ -573,6 +573,7 @@ ActiveRecord::Schema.define(version: 2019_11_25_140458) do ...@@ -573,6 +573,7 @@ ActiveRecord::Schema.define(version: 2019_11_25_140458) do
t.string "font" t.string "font"
t.text "message_html", null: false t.text "message_html", null: false
t.integer "cached_markdown_version" t.integer "cached_markdown_version"
t.string "target_path", limit: 255
t.index ["starts_at", "ends_at", "id"], name: "index_broadcast_messages_on_starts_at_and_ends_at_and_id" t.index ["starts_at", "ends_at", "id"], name: "index_broadcast_messages_on_starts_at_and_ends_at_and_id"
end end
......
...@@ -457,36 +457,40 @@ If Registry is enabled in your GitLab instance, but you don't need it for your ...@@ -457,36 +457,40 @@ If Registry is enabled in your GitLab instance, but you don't need it for your
project, you can disable it from your project's settings. Read the user guide project, you can disable it from your project's settings. Read the user guide
on how to achieve that. on how to achieve that.
## Disable Container Registry but use GitLab as an auth endpoint ## Use an external container registry with GitLab as an auth endpoint
**Omnibus GitLab** **Omnibus GitLab**
You can use GitLab as an auth endpoint and use a non-bundled Container Registry. You can use GitLab as an auth endpoint with an external container registry.
1. Open `/etc/gitlab/gitlab.rb` and set necessary configurations: 1. Open `/etc/gitlab/gitlab.rb` and set necessary configurations:
```ruby ```ruby
gitlab_rails['registry_enabled'] = true gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.gitlab.example.com"
gitlab_rails['registry_port'] = "5005"
gitlab_rails['registry_api_url'] = "http://localhost:5000" gitlab_rails['registry_api_url'] = "http://localhost:5000"
gitlab_rails['registry_path'] = "/var/opt/gitlab/gitlab-rails/shared/registry"
gitlab_rails['registry_issuer'] = "omnibus-gitlab-issuer" gitlab_rails['registry_issuer'] = "omnibus-gitlab-issuer"
``` ```
1. A certificate keypair is required for GitLab and the Container Registry to NOTE: **Note:**
communicate securely. By default Omnibus GitLab will generate one keypair, `gitlab_rails['registry_enabled'] = true` is needed to enable GitLab's
which is saved to `/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key`. Container Registry features and authentication endpoint. GitLab's bundled
When using a non-bundled Container Registry, you will need to supply a Container Registry service will not be started even with this enabled.
custom certificate key. To do that, add the following to
`/etc/gitlab/gitlab.rb` 1. A certificate-key pair is required for GitLab and the external container
registry to communicate securely. You will need to create a certificate-key
pair, configuring the external container registry with the public
certificate and configuring GitLab with the private key. To do that, add
the following to `/etc/gitlab/gitlab.rb`:
```ruby ```ruby
gitlab_rails['registry_key_path'] = "/custom/path/to/registry-key.key"
# registry['internal_key'] should contain the contents of the custom key # registry['internal_key'] should contain the contents of the custom key
# file. Line breaks in the key file should be marked using `\n` character # file. Line breaks in the key file should be marked using `\n` character
# Example: # Example:
registry['internal_key'] = "---BEGIN RSA PRIVATE KEY---\nMIIEpQIBAA\n" registry['internal_key'] = "---BEGIN RSA PRIVATE KEY---\nMIIEpQIBAA\n"
# Optionally define a custom file for Omnibus GitLab to write the contents
# of registry['internal_key'] to.
gitlab_rails['registry_key_path'] = "/custom/path/to/registry-key.key"
``` ```
NOTE: **Note:** NOTE: **Note:**
...@@ -496,7 +500,16 @@ You can use GitLab as an auth endpoint and use a non-bundled Container Registry. ...@@ -496,7 +500,16 @@ You can use GitLab as an auth endpoint and use a non-bundled Container Registry.
`/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key` and will populate `/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key` and will populate
it. it.
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. 1. To change the container registry URL displayed in the GitLab Container
Registry pages, set the following configurations:
```ruby
gitlab_rails['registry_host'] = "registry.gitlab.example.com"
gitlab_rails['registry_port'] = "5005"
```
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect.
**Installations from source** **Installations from source**
......
...@@ -108,15 +108,11 @@ class AddUsersLowerUsernameEmailIndexes < ActiveRecord::Migration[4.2] ...@@ -108,15 +108,11 @@ class AddUsersLowerUsernameEmailIndexes < ActiveRecord::Migration[4.2]
disable_ddl_transaction! disable_ddl_transaction!
def up def up
return unless Gitlab::Database.postgresql?
execute 'CREATE INDEX CONCURRENTLY index_on_users_lower_username ON users (LOWER(username));' execute 'CREATE INDEX CONCURRENTLY index_on_users_lower_username ON users (LOWER(username));'
execute 'CREATE INDEX CONCURRENTLY index_on_users_lower_email ON users (LOWER(email));' execute 'CREATE INDEX CONCURRENTLY index_on_users_lower_email ON users (LOWER(email));'
end end
def down def down
return unless Gitlab::Database.postgresql?
remove_index :users, :index_on_users_lower_username remove_index :users, :index_on_users_lower_username
remove_index :users, :index_on_users_lower_email remove_index :users, :index_on_users_lower_email
end end
......
...@@ -6,22 +6,16 @@ necessary to add database (version) specific behaviour. ...@@ -6,22 +6,16 @@ necessary to add database (version) specific behaviour.
To facilitate this we have the following methods that you can use: To facilitate this we have the following methods that you can use:
- `Gitlab::Database.postgresql?`: returns `true` if PostgreSQL is being used.
You can normally just assume this is the case.
- `Gitlab::Database.version`: returns the PostgreSQL version number as a string - `Gitlab::Database.version`: returns the PostgreSQL version number as a string
in the format `X.Y.Z`. in the format `X.Y.Z`.
This allows you to write code such as: This allows you to write code such as:
```ruby ```ruby
if Gitlab::Database.postgresql? if Gitlab::Database.version.to_f >= 9.6
if Gitlab::Database.version.to_f >= 9.6 run_really_fast_query
run_really_fast_query
else
run_fast_query
end
else else
run_query run_fast_query
end end
``` ```
......
...@@ -166,3 +166,36 @@ via Omnibus, or [restart GitLab] if you installed from source. ...@@ -166,3 +166,36 @@ via Omnibus, or [restart GitLab] if you installed from source.
[reconfigure GitLab]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure [reconfigure GitLab]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
[restart GitLab]: ../administration/restart_gitlab.md#installations-from-source [restart GitLab]: ../administration/restart_gitlab.md#installations-from-source
## Troubleshooting
### Error 500 when trying to sign in to GitLab via GitHub Enterprise
Check the [`production.log`](../administration/logs.md#productionlog)
on your GitLab server to obtain further details. If you are getting the error like
`Faraday::ConnectionFailed (execution expired)` in the log, there may be a connectivity issue
between your GitLab instance and GitHub Enterprise. To verify it, [start the rails console](https://docs.gitlab.com/omnibus/maintenance/#starting-a-rails-console-session)
and run the commands below replacing <github_url> with the URL of your GitHub Enterprise instance:
```ruby
uri = URI.parse("https://<github_url>") # replace `GitHub-URL` with the real one here
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = 1
response = http.request(Net::HTTP::Get.new(uri.request_uri))
```
If you are getting a similar `execution expired` error, it confirms the theory about the
network connectivity. In that case, make sure that the GitLab server is able to reach your
GitHub enterprise instance.
### Signing in using your GitHub account without a pre-existing GitLab account is not allowed
If you're getting the message `Signing in using your GitHub account without a pre-existing
GitLab account is not allowed. Create a GitLab account first, and then connect it to your
GitHub account` when signing in, in GitLab:
1. Go to your **Profile > Account**.
1. Under the "Social sign-in" section, click **Connect** near the GitHub icon.
After that, you should be able to sign in via GitHub successfully.
...@@ -22,6 +22,7 @@ To add a broadcast message: ...@@ -22,6 +22,7 @@ To add a broadcast message:
1. Navigate to the **Admin Area > Messages** page. 1. Navigate to the **Admin Area > Messages** page.
1. Add the text for the message to the **Message** field. Markdown and emoji are supported. 1. Add the text for the message to the **Message** field. Markdown and emoji are supported.
1. If required, click the **Customize colors** link to edit the background color and font color of the message. 1. If required, click the **Customize colors** link to edit the background color and font color of the message.
1. If required, add a **Target Path** to only show the broadcast message on URLs matching that path. You can use the wildcard character `*` to match multiple URLs, for example `/users/*/issues`.
1. Select a date for the message to start and end. 1. Select a date for the message to start and end.
1. Click the **Add broadcast message** button. 1. Click the **Add broadcast message** button.
......
...@@ -123,8 +123,6 @@ module Gitlab ...@@ -123,8 +123,6 @@ module Gitlab
end end
def add_missing_db_timezone def add_missing_db_timezone
return '' unless Gitlab::Database.postgresql?
'at time zone \'UTC\'' 'at time zone \'UTC\''
end end
end end
......
...@@ -9650,6 +9650,9 @@ msgstr "" ...@@ -9650,6 +9650,9 @@ msgstr ""
msgid "Issue" msgid "Issue"
msgstr "" msgstr ""
msgid "Issue %{issue_reference} has already been added to epic %{epic_reference}."
msgstr ""
msgid "Issue Boards" msgid "Issue Boards"
msgstr "" msgstr ""
...@@ -12263,6 +12266,9 @@ msgstr "" ...@@ -12263,6 +12266,9 @@ msgstr ""
msgid "Path:" msgid "Path:"
msgstr "" msgstr ""
msgid "Paths can contain wildcards, like */welcome"
msgstr ""
msgid "Pause" msgid "Pause"
msgstr "" msgstr ""
...@@ -16836,7 +16842,7 @@ msgstr "" ...@@ -16836,7 +16842,7 @@ msgstr ""
msgid "Subscriptions" msgid "Subscriptions"
msgstr "" msgstr ""
msgid "Subscriptions allow successfully completed pipelines on the %{default_branch_docs} of the subscribed project to trigger a new pipeline on thee default branch of this project." msgid "Subscriptions allow successfully completed pipelines on the %{default_branch_docs} of the subscribed project to trigger a new pipeline on the default branch of this project."
msgstr "" msgstr ""
msgid "Subtracted" msgid "Subtracted"
...@@ -17109,6 +17115,9 @@ msgstr "" ...@@ -17109,6 +17115,9 @@ msgstr ""
msgid "Target Branch" msgid "Target Branch"
msgstr "" msgstr ""
msgid "Target Path"
msgstr ""
msgid "Target branch" msgid "Target branch"
msgstr "" msgstr ""
......
...@@ -13,7 +13,7 @@ describe Admin::IdentitiesController do ...@@ -13,7 +13,7 @@ describe Admin::IdentitiesController do
let(:user) { create(:omniauth_user, provider: 'ldapmain', extern_uid: 'uid=myuser,ou=people,dc=example,dc=com') } let(:user) { create(:omniauth_user, provider: 'ldapmain', extern_uid: 'uid=myuser,ou=people,dc=example,dc=com') }
it 'repairs ldap blocks' do it 'repairs ldap blocks' do
expect_next_instance_of(RepairLdapBlockedUserService) do |instance| expect_next_instance_of(::Users::RepairLdapBlockedService) do |instance|
expect(instance).to receive(:execute) expect(instance).to receive(:execute)
end end
...@@ -25,7 +25,7 @@ describe Admin::IdentitiesController do ...@@ -25,7 +25,7 @@ describe Admin::IdentitiesController do
let(:user) { create(:omniauth_user, provider: 'ldapmain', extern_uid: 'uid=myuser,ou=people,dc=example,dc=com') } let(:user) { create(:omniauth_user, provider: 'ldapmain', extern_uid: 'uid=myuser,ou=people,dc=example,dc=com') }
it 'repairs ldap blocks' do it 'repairs ldap blocks' do
expect_next_instance_of(RepairLdapBlockedUserService) do |instance| expect_next_instance_of(::Users::RepairLdapBlockedService) do |instance|
expect(instance).to receive(:execute) expect(instance).to receive(:execute)
end end
......
# frozen_string_literal: true
FactoryBot.define do
factory :merge_request_diff_commit do
association :merge_request_diff
sha { Digest::SHA1.hexdigest(SecureRandom.hex) }
relative_order { 0 }
end
end
...@@ -16,12 +16,14 @@ describe 'Admin Broadcast Messages' do ...@@ -16,12 +16,14 @@ describe 'Admin Broadcast Messages' do
it 'Create a customized broadcast message' do it 'Create a customized broadcast message' do
fill_in 'broadcast_message_message', with: 'Application update from **4:00 CST to 5:00 CST**' fill_in 'broadcast_message_message', with: 'Application update from **4:00 CST to 5:00 CST**'
fill_in 'broadcast_message_color', with: '#f2dede' fill_in 'broadcast_message_color', with: '#f2dede'
fill_in 'broadcast_message_target_path', with: '*/user_onboarded'
fill_in 'broadcast_message_font', with: '#b94a48' fill_in 'broadcast_message_font', with: '#b94a48'
select Date.today.next_year.year, from: 'broadcast_message_ends_at_1i' select Date.today.next_year.year, from: 'broadcast_message_ends_at_1i'
click_button 'Add broadcast message' click_button 'Add broadcast message'
expect(current_path).to eq admin_broadcast_messages_path expect(current_path).to eq admin_broadcast_messages_path
expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST' expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
expect(page).to have_content '*/user_onboarded'
expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST' expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
expect(page).to have_selector %(div[style="background-color: #f2dede; color: #b94a48"]) expect(page).to have_selector %(div[style="background-color: #f2dede; color: #b94a48"])
end end
......
...@@ -635,43 +635,39 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do ...@@ -635,43 +635,39 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
end end
context 'JSON with invalid records' do context 'JSON with invalid records' do
subject(:restored_project_json) { project_tree_restorer.restore }
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:project) { create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') } let!(:project) { create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') }
let(:project_tree_restorer) { described_class.new(user: user, shared: shared, project: project) } let(:project_tree_restorer) { described_class.new(user: user, shared: shared, project: project) }
let(:restored_project_json) { project_tree_restorer.restore } let(:correlation_id) { 'my-correlation-id' }
context 'when some failures occur' do
context 'because a relation fails to be processed' do
let(:correlation_id) { 'my-correlation-id' }
before do before do
setup_import_export_config('with_invalid_records') setup_import_export_config('with_invalid_records')
Labkit::Correlation::CorrelationId.use_id(correlation_id) do Labkit::Correlation::CorrelationId.use_id(correlation_id) { subject }
expect(restored_project_json).to eq(true) end
end
end
it_behaves_like 'restores project successfully', context 'when failures occur because a relation fails to be processed' do
issues: 0, it_behaves_like 'restores project successfully',
labels: 0, issues: 0,
label_with_priorities: nil, labels: 0,
milestones: 1, label_with_priorities: nil,
first_issue_labels: 0, milestones: 1,
services: 0, first_issue_labels: 0,
import_failures: 1 services: 0,
import_failures: 1
it 'records the failures in the database' do
import_failure = ImportFailure.last it 'records the failures in the database' do
import_failure = ImportFailure.last
expect(import_failure.project_id).to eq(project.id)
expect(import_failure.relation_key).to eq('milestones') expect(import_failure.project_id).to eq(project.id)
expect(import_failure.relation_index).to be_present expect(import_failure.relation_key).to eq('milestones')
expect(import_failure.exception_class).to eq('ActiveRecord::RecordInvalid') expect(import_failure.relation_index).to be_present
expect(import_failure.exception_message).to be_present expect(import_failure.exception_class).to eq('ActiveRecord::RecordInvalid')
expect(import_failure.correlation_id_value).to eq('my-correlation-id') expect(import_failure.exception_message).to be_present
expect(import_failure.created_at).to be_present expect(import_failure.correlation_id_value).to eq('my-correlation-id')
end expect(import_failure.created_at).to be_present
end end
end end
end end
......
...@@ -88,6 +88,42 @@ describe BroadcastMessage do ...@@ -88,6 +88,42 @@ describe BroadcastMessage do
expect(Rails.cache).not_to receive(:delete).with(described_class::CACHE_KEY) expect(Rails.cache).not_to receive(:delete).with(described_class::CACHE_KEY)
expect(described_class.current.length).to eq(0) expect(described_class.current.length).to eq(0)
end end
it 'returns message if it matches the target path' do
message = create(:broadcast_message, target_path: "*/onboarding_completed")
expect(described_class.current('/users/onboarding_completed')).to include(message)
end
it 'returns message if part of the target path matches' do
create(:broadcast_message, target_path: "/users/*/issues")
expect(described_class.current('/users/name/issues').length).to eq(1)
end
it 'returns the message for empty target path' do
create(:broadcast_message, target_path: "")
expect(described_class.current('/users/name/issues').length).to eq(1)
end
it 'returns the message if target path is nil' do
create(:broadcast_message, target_path: nil)
expect(described_class.current('/users/name/issues').length).to eq(1)
end
it 'does not return message if target path does not match' do
create(:broadcast_message, target_path: "/onboarding_completed")
expect(described_class.current('/welcome').length).to eq(0)
end
it 'does not return message if target path does not match when using wildcard' do
create(:broadcast_message, target_path: "/users/*/issues")
expect(described_class.current('/group/groupname/issues').length).to eq(0)
end
end end
describe '#attributes' do describe '#attributes' do
......
...@@ -75,7 +75,9 @@ describe MergeRequest::Pipelines do ...@@ -75,7 +75,9 @@ describe MergeRequest::Pipelines do
let(:shas) { project.repository.commits(source_ref, limit: 2).map(&:id) } let(:shas) { project.repository.commits(source_ref, limit: 2).map(&:id) }
before do before do
allow(merge_request).to receive(:all_commit_shas) { shas } create(:merge_request_diff_commit,
merge_request_diff: merge_request.merge_request_diff,
sha: shas.second, relative_order: 1)
end end
it 'returns merge request pipeline first' do it 'returns merge request pipeline first' do
...@@ -119,7 +121,11 @@ describe MergeRequest::Pipelines do ...@@ -119,7 +121,11 @@ describe MergeRequest::Pipelines do
end end
before do before do
allow(merge_request_2).to receive(:all_commit_shas) { shas } shas.each.with_index do |sha, index|
create(:merge_request_diff_commit,
merge_request_diff: merge_request_2.merge_request_diff,
sha: sha, relative_order: index)
end
end end
it 'returns only related merge request pipelines' do it 'returns only related merge request pipelines' do
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe RepairLdapBlockedUserService do describe Users::RepairLdapBlockedService do
let(:user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') } let(:user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') }
let(:identity) { user.ldap_identity } let(:identity) { user.ldap_identity }
subject(:service) { described_class.new(user) } subject(:service) { described_class.new(user) }
......
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