Commit 6f105fa0 authored by Tiger Watson's avatar Tiger Watson

Merge branch 'move-gitlab-database-readonly' into 'master'

[RUN AS-IF-FOSS] Move read_only/read_write back to Gitlab::Database

See merge request gitlab-org/gitlab!67149
parents 754321b7 bc197247
...@@ -71,7 +71,7 @@ class Admin::SessionsController < ApplicationController ...@@ -71,7 +71,7 @@ class Admin::SessionsController < ApplicationController
::Users::ValidateOtpService.new(user).execute(user_params[:otp_attempt]) ::Users::ValidateOtpService.new(user).execute(user_params[:otp_attempt])
valid_otp_attempt = otp_validation_result[:status] == :success valid_otp_attempt = otp_validation_result[:status] == :success
return valid_otp_attempt if Gitlab::Database.main.read_only? return valid_otp_attempt if Gitlab::Database.read_only?
valid_otp_attempt || user.invalidate_otp_backup_code!(user_params[:otp_attempt]) valid_otp_attempt || user.invalidate_otp_backup_code!(user_params[:otp_attempt])
end end
......
...@@ -27,7 +27,7 @@ module Boards ...@@ -27,7 +27,7 @@ module Boards
list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params) list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params)
issues = issues_from(list_service) issues = issues_from(list_service)
if Gitlab::Database.main.read_write? && !board.disabled_for?(current_user) if Gitlab::Database.read_write? && !board.disabled_for?(current_user)
Issue.move_nulls_to_end(issues) Issue.move_nulls_to_end(issues)
end end
......
...@@ -47,7 +47,7 @@ module AuthenticatesWithTwoFactorForAdminMode ...@@ -47,7 +47,7 @@ module AuthenticatesWithTwoFactorForAdminMode
# Remove any lingering user data from login # Remove any lingering user data from login
session.delete(:otp_user_id) session.delete(:otp_user_id)
user.save! unless Gitlab::Database.main.read_only? user.save! unless Gitlab::Database.read_only?
# The admin user has successfully passed 2fa, enable admin mode ignoring password # The admin user has successfully passed 2fa, enable admin mode ignoring password
enable_admin_mode enable_admin_mode
......
...@@ -148,7 +148,7 @@ module IssuableActions ...@@ -148,7 +148,7 @@ module IssuableActions
# on GET requests. # on GET requests.
# This is just a fail-safe in case notes_filter is sent via GET request in GitLab Geo. # This is just a fail-safe in case notes_filter is sent via GET request in GitLab Geo.
# In some cases, we also force the filter to not be persisted with the `persist_filter` param # In some cases, we also force the filter to not be persisted with the `persist_filter` param
if Gitlab::Database.main.read_only? || params[:persist_filter] == 'false' if Gitlab::Database.read_only? || params[:persist_filter] == 'false'
notes_filter_param || current_user&.notes_filter_for(issuable) notes_filter_param || current_user&.notes_filter_for(issuable)
else else
notes_filter = current_user&.set_notes_filter(notes_filter_param, issuable) || notes_filter_param notes_filter = current_user&.set_notes_filter(notes_filter_param, issuable) || notes_filter_param
......
...@@ -17,7 +17,7 @@ module RecordUserLastActivity ...@@ -17,7 +17,7 @@ module RecordUserLastActivity
def set_user_last_activity def set_user_last_activity
return unless request.get? return unless request.get?
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
if current_user && current_user.last_activity_on != Date.today if current_user && current_user.last_activity_on != Date.today
Users::ActivityService.new(current_user).execute Users::ActivityService.new(current_user).execute
......
...@@ -41,7 +41,7 @@ module SortingPreference ...@@ -41,7 +41,7 @@ module SortingPreference
sort_param = params[:sort] sort_param = params[:sort]
sort_param ||= user_preference[field] sort_param ||= user_preference[field]
return sort_param if Gitlab::Database.main.read_only? return sort_param if Gitlab::Database.read_only?
if user_preference[field] != sort_param if user_preference[field] != sort_param
user_preference.update(field => sort_param) user_preference.update(field => sort_param)
......
...@@ -77,7 +77,7 @@ module Repositories ...@@ -77,7 +77,7 @@ module Repositories
def update_fetch_statistics def update_fetch_statistics
return unless project return unless project
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
return unless repo_type.project? return unless repo_type.project?
OnboardingProgressService.async(project.namespace_id).execute(action: :git_pull) OnboardingProgressService.async(project.namespace_id).execute(action: :git_pull)
......
...@@ -126,7 +126,7 @@ module Repositories ...@@ -126,7 +126,7 @@ module Repositories
# Overridden in EE # Overridden in EE
def batch_operation_disallowed? def batch_operation_disallowed?
upload_request? && Gitlab::Database.main.read_only? upload_request? && Gitlab::Database.read_only?
end end
# Overridden in EE # Overridden in EE
......
...@@ -29,7 +29,7 @@ module Mutations ...@@ -29,7 +29,7 @@ module Mutations
end end
def ready?(**args) def ready?(**args)
raise_resource_not_available_error! ERROR_MESSAGE if Gitlab::Database.main.read_only? raise_resource_not_available_error! ERROR_MESSAGE if Gitlab::Database.read_only?
missing_args = self.class.arguments.values missing_args = self.class.arguments.values
.reject { |arg| arg.accepts?(args.fetch(arg.keyword, :not_given)) } .reject { |arg| arg.accepts?(args.fetch(arg.keyword, :not_given)) }
......
...@@ -344,7 +344,7 @@ module ApplicationHelper ...@@ -344,7 +344,7 @@ module ApplicationHelper
# Overridden in EE # Overridden in EE
def read_only_message def read_only_message
return unless Gitlab::Database.main.read_only? return unless Gitlab::Database.read_only?
_('You are on a read-only GitLab instance.') _('You are on a read-only GitLab instance.')
end end
......
...@@ -34,7 +34,7 @@ module DeprecatedAssignee ...@@ -34,7 +34,7 @@ module DeprecatedAssignee
end end
def assignee_ids def assignee_ids
if Gitlab::Database.main.read_only? && pending_assignees_population? if Gitlab::Database.read_only? && pending_assignees_population?
return Array(deprecated_assignee_id) return Array(deprecated_assignee_id)
end end
...@@ -43,7 +43,7 @@ module DeprecatedAssignee ...@@ -43,7 +43,7 @@ module DeprecatedAssignee
end end
def assignees def assignees
if Gitlab::Database.main.read_only? && pending_assignees_population? if Gitlab::Database.read_only? && pending_assignees_population?
return User.where(id: deprecated_assignee_id) return User.where(id: deprecated_assignee_id)
end end
...@@ -56,7 +56,7 @@ module DeprecatedAssignee ...@@ -56,7 +56,7 @@ module DeprecatedAssignee
# This will make the background migration process quicker (#26496) as it'll have less # This will make the background migration process quicker (#26496) as it'll have less
# assignee_id rows to look through. # assignee_id rows to look through.
def nullify_deprecated_assignee def nullify_deprecated_assignee
return unless persisted? && Gitlab::Database.main.read_only? return unless persisted? && Gitlab::Database.read_only?
update_column(:assignee_id, nil) update_column(:assignee_id, nil)
end end
......
...@@ -41,7 +41,7 @@ module TokenAuthenticatableStrategies ...@@ -41,7 +41,7 @@ module TokenAuthenticatableStrategies
# Resets the token, but only saves when the database is in read & write mode # Resets the token, but only saves when the database is in read & write mode
def reset_token!(instance) def reset_token!(instance)
write_new_token(instance) write_new_token(instance)
instance.save! if Gitlab::Database.main.read_write? instance.save! if Gitlab::Database.read_write?
end end
def self.fabricate(model, field, options) def self.fabricate(model, field, options)
......
...@@ -2818,11 +2818,11 @@ class Project < ApplicationRecord ...@@ -2818,11 +2818,11 @@ class Project < ApplicationRecord
end end
def cache_has_external_wiki def cache_has_external_wiki
update_column(:has_external_wiki, integrations.external_wikis.any?) if Gitlab::Database.main.read_write? update_column(:has_external_wiki, integrations.external_wikis.any?) if Gitlab::Database.read_write?
end end
def cache_has_external_issue_tracker def cache_has_external_issue_tracker
update_column(:has_external_issue_tracker, integrations.external_issue_trackers.any?) if Gitlab::Database.main.read_write? update_column(:has_external_issue_tracker, integrations.external_issue_trackers.any?) if Gitlab::Database.read_write?
end end
def active_runners_with_tags def active_runners_with_tags
......
...@@ -38,7 +38,7 @@ class ProjectStatistics < ApplicationRecord ...@@ -38,7 +38,7 @@ class ProjectStatistics < ApplicationRecord
end end
def refresh!(only: []) def refresh!(only: [])
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
COLUMNS_TO_REFRESH.each do |column, generator| COLUMNS_TO_REFRESH.each do |column, generator|
if only.empty? || only.include?(column) if only.empty? || only.include?(column)
......
...@@ -34,7 +34,7 @@ class SnippetStatistics < ApplicationRecord ...@@ -34,7 +34,7 @@ class SnippetStatistics < ApplicationRecord
end end
def refresh! def refresh!
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
update_commit_count update_commit_count
update_repository_size update_repository_size
......
...@@ -80,7 +80,7 @@ class User < ApplicationRecord ...@@ -80,7 +80,7 @@ class User < ApplicationRecord
# to limit database writes to at most once every hour # to limit database writes to at most once every hour
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
def update_tracked_fields!(request) def update_tracked_fields!(request)
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
update_tracked_fields(request) update_tracked_fields(request)
...@@ -363,7 +363,7 @@ class User < ApplicationRecord ...@@ -363,7 +363,7 @@ class User < ApplicationRecord
end end
before_transition do before_transition do
!Gitlab::Database.main.read_only? !Gitlab::Database.read_only?
end end
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
...@@ -848,11 +848,11 @@ class User < ApplicationRecord ...@@ -848,11 +848,11 @@ class User < ApplicationRecord
end end
def remember_me! def remember_me!
super if ::Gitlab::Database.main.read_write? super if ::Gitlab::Database.read_write?
end end
def forget_me! def forget_me!
super if ::Gitlab::Database.main.read_write? super if ::Gitlab::Database.read_write?
end end
def disable_two_factor! def disable_two_factor!
...@@ -1751,7 +1751,7 @@ class User < ApplicationRecord ...@@ -1751,7 +1751,7 @@ class User < ApplicationRecord
# #
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
def increment_failed_attempts! def increment_failed_attempts!
return if ::Gitlab::Database.main.read_only? return if ::Gitlab::Database.read_only?
increment_failed_attempts increment_failed_attempts
...@@ -1995,7 +1995,7 @@ class User < ApplicationRecord ...@@ -1995,7 +1995,7 @@ class User < ApplicationRecord
def consume_otp! def consume_otp!
if self.consumed_timestep != current_otp_timestep if self.consumed_timestep != current_otp_timestep
self.consumed_timestep = current_otp_timestep self.consumed_timestep = current_otp_timestep
return Gitlab::Database.main.read_only? ? true : save(validate: false) return Gitlab::Database.read_only? ? true : save(validate: false)
end end
false false
......
...@@ -111,7 +111,7 @@ class AuditEventService ...@@ -111,7 +111,7 @@ class AuditEventService
end end
def log_security_event_to_database def log_security_event_to_database
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
event = AuditEvent.new(base_payload.merge(details: @details)) event = AuditEvent.new(base_payload.merge(details: @details))
save_or_track event save_or_track event
...@@ -120,7 +120,7 @@ class AuditEventService ...@@ -120,7 +120,7 @@ class AuditEventService
end end
def log_authentication_event_to_database def log_authentication_event_to_database
return unless Gitlab::Database.main.read_write? && authentication_event? return unless Gitlab::Database.read_write? && authentication_event?
event = AuthenticationEvent.new(authentication_event_payload) event = AuthenticationEvent.new(authentication_event_payload)
save_or_track event save_or_track event
......
...@@ -4,7 +4,7 @@ module Boards ...@@ -4,7 +4,7 @@ module Boards
module Visits module Visits
class CreateService < Boards::BaseService class CreateService < Boards::BaseService
def execute(board) def execute(board)
return unless current_user && Gitlab::Database.main.read_write? return unless current_user && Gitlab::Database.read_write?
return unless board return unless board
model.visited!(current_user, board) model.visited!(current_user, board)
......
...@@ -18,7 +18,7 @@ module Keys ...@@ -18,7 +18,7 @@ module Keys
end end
def update? def update?
return false if ::Gitlab::Database.main.read_only? return false if ::Gitlab::Database.read_only?
last_used = key.last_used_at last_used = key.last_used_at
......
...@@ -166,7 +166,7 @@ module MergeRequests ...@@ -166,7 +166,7 @@ module MergeRequests
strong_memoize(:service_error) do strong_memoize(:service_error) do
if !merge_request if !merge_request
ServiceResponse.error(message: 'Invalid argument') ServiceResponse.error(message: 'Invalid argument')
elsif Gitlab::Database.main.read_only? elsif Gitlab::Database.read_only?
ServiceResponse.error(message: 'Unsupported operation') ServiceResponse.error(message: 'Unsupported operation')
end end
end end
......
...@@ -11,7 +11,7 @@ module Packages ...@@ -11,7 +11,7 @@ module Packages
::Gitlab::UsageDataCounters::PackageEventCounter.count(event_name) ::Gitlab::UsageDataCounters::PackageEventCounter.count(event_name)
end end
if Feature.enabled?(:collect_package_events) && Gitlab::Database.main.read_write? if Feature.enabled?(:collect_package_events) && Gitlab::Database.read_write?
::Packages::Event.create!( ::Packages::Event.create!(
event_type: event_name, event_type: event_name,
originator: current_user&.id, originator: current_user&.id,
......
...@@ -18,7 +18,7 @@ module PersonalAccessTokens ...@@ -18,7 +18,7 @@ module PersonalAccessTokens
private private
def update? def update?
return false if ::Gitlab::Database.main.read_only? return false if ::Gitlab::Database.read_only?
last_used = @personal_access_token.last_used_at last_used = @personal_access_token.last_used_at
......
...@@ -19,7 +19,7 @@ class Repositories::DestroyService < Repositories::BaseService ...@@ -19,7 +19,7 @@ class Repositories::DestroyService < Repositories::BaseService
# never be triggered on a read-only instance. # never be triggered on a read-only instance.
# #
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/223272 # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/223272
if Gitlab::Database.main.read_only? if Gitlab::Database.read_only?
Repositories::ShellDestroyService.new(current_repository).execute Repositories::ShellDestroyService.new(current_repository).execute
else else
container.run_after_commit do container.run_after_commit do
......
...@@ -23,7 +23,7 @@ module Users ...@@ -23,7 +23,7 @@ module Users
private private
def record_activity def record_activity
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
today = Date.today today = Date.today
......
...@@ -124,7 +124,7 @@ module GitGarbageCollectMethods ...@@ -124,7 +124,7 @@ module GitGarbageCollectMethods
def update_repository_statistics(resource) def update_repository_statistics(resource)
resource.repository.expire_statistics_caches resource.repository.expire_statistics_caches
return if Gitlab::Database.main.read_only? # GitGarbageCollectWorker may be run on a Geo secondary return if Gitlab::Database.read_only? # GitGarbageCollectWorker may be run on a Geo secondary
update_db_repository_statistics(resource) update_db_repository_statistics(resource)
end end
......
...@@ -11,7 +11,7 @@ class PagesDomainVerificationCronWorker # rubocop:disable Scalability/Idempotent ...@@ -11,7 +11,7 @@ class PagesDomainVerificationCronWorker # rubocop:disable Scalability/Idempotent
worker_resource_boundary :cpu worker_resource_boundary :cpu
def perform def perform
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
PagesDomain.needs_verification.with_logging_info.find_each do |domain| PagesDomain.needs_verification.with_logging_info.find_each do |domain|
with_context(project: domain.project) do with_context(project: domain.project) do
......
...@@ -12,7 +12,7 @@ class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWork ...@@ -12,7 +12,7 @@ class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWork
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform(domain_id) def perform(domain_id)
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
domain = PagesDomain.find_by(id: domain_id) domain = PagesDomain.find_by(id: domain_id)
......
...@@ -44,7 +44,7 @@ class ProjectCacheWorker ...@@ -44,7 +44,7 @@ class ProjectCacheWorker
# statistics to become accurate if they were already updated once in the # statistics to become accurate if they were already updated once in the
# last 15 minutes. # last 15 minutes.
def update_statistics(project, statistics = []) def update_statistics(project, statistics = [])
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
return unless try_obtain_lease_for(project.id, statistics) return unless try_obtain_lease_for(project.id, statistics)
Projects::UpdateStatisticsService.new(project, nil, statistics: statistics).execute Projects::UpdateStatisticsService.new(project, nil, statistics: statistics).execute
......
...@@ -23,7 +23,7 @@ module Projects ...@@ -23,7 +23,7 @@ module Projects
end end
def cleanup_orphan_lfs_file_references(resource) def cleanup_orphan_lfs_file_references(resource)
return if Gitlab::Database.main.read_only? # GitGarbageCollectWorker may be run on a Geo secondary return if Gitlab::Database.read_only? # GitGarbageCollectWorker may be run on a Geo secondary
::Gitlab::Cleanup::OrphanLfsFileReferences.new(resource, dry_run: false, logger: logger).run! ::Gitlab::Cleanup::OrphanLfsFileReferences.new(resource, dry_run: false, logger: logger).run!
rescue StandardError => err rescue StandardError => err
......
...@@ -12,7 +12,7 @@ class ScheduleMergeRequestCleanupRefsWorker ...@@ -12,7 +12,7 @@ class ScheduleMergeRequestCleanupRefsWorker
idempotent! idempotent!
def perform def perform
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
return unless Feature.enabled?(:merge_request_refs_cleanup, default_enabled: false) return unless Feature.enabled?(:merge_request_refs_cleanup, default_enabled: false)
MergeRequestCleanupRefsWorker.perform_with_capacity MergeRequestCleanupRefsWorker.perform_with_capacity
......
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
# `Shard.connected?` could be cached and return true even though the table doesn't exist # `Shard.connected?` could be cached and return true even though the table doesn't exist
return unless Shard.connected? return unless Shard.connected?
return unless ActiveRecord::Migrator.current_version >= 20190402150158 return unless ActiveRecord::Migrator.current_version >= 20190402150158
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
Shard.populate! Shard.populate!
...@@ -445,7 +445,7 @@ module EE ...@@ -445,7 +445,7 @@ module EE
override :perform override :perform
def perform(table_name = EVENT_TABLES.first) def perform(table_name = EVENT_TABLES.first)
return if ::Gitlab::Database.main.read_only? return if ::Gitlab::Database.read_only?
deleted_rows = prune_orphaned_rows(table_name) deleted_rows = prune_orphaned_rows(table_name)
table_name = next_table(table_name) if deleted_rows.zero? table_name = next_table(table_name) if deleted_rows.zero?
......
...@@ -368,12 +368,12 @@ All Geo **secondary** nodes are read-only. ...@@ -368,12 +368,12 @@ All Geo **secondary** nodes are read-only.
The general principle of a [read-only database](verifying_database_capabilities.md#read-only-database) The general principle of a [read-only database](verifying_database_capabilities.md#read-only-database)
applies to all Geo **secondary** nodes. So the applies to all Geo **secondary** nodes. So the
`Gitlab::Database.main.read_only?` method will always return `true` on a `Gitlab::Database.read_only?` method will always return `true` on a
**secondary** node. **secondary** node.
When some write actions are not allowed because the node is a When some write actions are not allowed because the node is a
**secondary**, consider adding the `Gitlab::Database.main.read_only?` or **secondary**, consider adding the `Gitlab::Database.read_only?` or
`Gitlab::Database.main.read_write?` guard, instead of `Gitlab::Geo.secondary?`. `Gitlab::Database.read_write?` guard, instead of `Gitlab::Geo.secondary?`.
The database itself will already be read-only in a replicated setup, The database itself will already be read-only in a replicated setup,
so we don't need to take any extra step for that. so we don't need to take any extra step for that.
......
...@@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab Maintenance Mode **only** blocks writes from HTTP and SSH requests at the application level in a few key places within the rails application. GitLab Maintenance Mode **only** blocks writes from HTTP and SSH requests at the application level in a few key places within the rails application.
[Search the codebase for `maintenance_mode?`.](https://gitlab.com/search?search=maintenance_mode%3F&group_id=9970&project_id=278964&scope=blobs&search_code=false&snippets=false&repository_ref=) [Search the codebase for `maintenance_mode?`.](https://gitlab.com/search?search=maintenance_mode%3F&group_id=9970&project_id=278964&scope=blobs&search_code=false&snippets=false&repository_ref=)
- [the read-only database method](https://gitlab.com/gitlab-org/gitlab/-/blob/2425e9de50c678413ceaad6ee3bf66f42b7e228c/ee/lib/ee/gitlab/database.rb#L13), which toggles special behavior when we are not allowed to write to the database. [Search the codebase for `Gitlab::Database.main.read_only?`.](https://gitlab.com/search?search=Gitlab%3A%3ADatabase.read_only%3F&group_id=9970&project_id=278964&scope=blobs&search_code=false&snippets=false&repository_ref=) - [the read-only database method](https://gitlab.com/gitlab-org/gitlab/-/blob/2425e9de50c678413ceaad6ee3bf66f42b7e228c/ee/lib/ee/gitlab/database.rb#L13), which toggles special behavior when we are not allowed to write to the database. [Search the codebase for `Gitlab::Database.read_only?`.](https://gitlab.com/search?search=Gitlab%3A%3ADatabase.read_only%3F&group_id=9970&project_id=278964&scope=blobs&search_code=false&snippets=false&repository_ref=)
- [the read-only middleware](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/ee/gitlab/middleware/read_only/controller.rb), where HTTP requests that cause database writes are blocked, unless explicitly allowed. - [the read-only middleware](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/ee/gitlab/middleware/read_only/controller.rb), where HTTP requests that cause database writes are blocked, unless explicitly allowed.
- [Git push access via SSH is denied](https://gitlab.com/gitlab-org/gitlab/-/blob/2425e9de50c678413ceaad6ee3bf66f42b7e228c/ee/lib/ee/gitlab/git_access.rb#L13) by returning 401 when `gitlab-shell` POSTs to [`/internal/allowed`](internal_api.md) to [check if access is allowed](internal_api.md#git-authentication). - [Git push access via SSH is denied](https://gitlab.com/gitlab-org/gitlab/-/blob/2425e9de50c678413ceaad6ee3bf66f42b7e228c/ee/lib/ee/gitlab/git_access.rb#L13) by returning 401 when `gitlab-shell` POSTs to [`/internal/allowed`](internal_api.md) to [check if access is allowed](internal_api.md#git-authentication).
- [Container registry authentication service](https://gitlab.com/gitlab-org/gitlab/-/blob/2425e9de50c678413ceaad6ee3bf66f42b7e228c/ee/app/services/ee/auth/container_registry_authentication_service.rb#L12), where updates to the container registry are blocked. - [Container registry authentication service](https://gitlab.com/gitlab-org/gitlab/-/blob/2425e9de50c678413ceaad6ee3bf66f42b7e228c/ee/app/services/ee/auth/container_registry_authentication_service.rb#L12), where updates to the container registry are blocked.
......
...@@ -30,7 +30,7 @@ end ...@@ -30,7 +30,7 @@ end
The database can be used in read-only mode. In this case we have to The database can be used in read-only mode. In this case we have to
make sure all GET requests don't attempt any write operations to the make sure all GET requests don't attempt any write operations to the
database. If one of those requests wants to write to the database, it needs database. If one of those requests wants to write to the database, it needs
to be wrapped in a `Gitlab::Database.main.read_only?` or `Gitlab::Database.main.read_write?` to be wrapped in a `Gitlab::Database.read_only?` or `Gitlab::Database.read_write?`
guard, to make sure it doesn't for read-only databases. guard, to make sure it doesn't for read-only databases.
We have a Rails Middleware that filters any potentially writing We have a Rails Middleware that filters any potentially writing
......
...@@ -54,7 +54,7 @@ module Groups ...@@ -54,7 +54,7 @@ module Groups
if params[:state].present? if params[:state].present?
preference.roadmap_epics_state = Epic.state_ids[params[:state]] preference.roadmap_epics_state = Epic.state_ids[params[:state]]
preference.save if preference.changed? && Gitlab::Database.main.read_write? preference.save if preference.changed? && Gitlab::Database.read_write?
end end
Epic.state_ids.key(preference.roadmap_epics_state) Epic.state_ids.key(preference.roadmap_epics_state)
......
...@@ -131,7 +131,7 @@ module EE ...@@ -131,7 +131,7 @@ module EE
end end
def show_ultimate_trial_suitable_env? def show_ultimate_trial_suitable_env?
::Gitlab.com? && !::Gitlab::Database.main.read_only? ::Gitlab.com? && !::Gitlab::Database.read_only?
end end
def token_expiration_enforced? def token_expiration_enforced?
......
...@@ -454,7 +454,7 @@ module EE ...@@ -454,7 +454,7 @@ module EE
def generate_subscription def generate_subscription
return unless persisted? return unless persisted?
return if ::Gitlab::Database.main.read_only? return if ::Gitlab::Database.read_only?
create_gitlab_subscription( create_gitlab_subscription(
plan_code: Plan::FREE, plan_code: Plan::FREE,
......
...@@ -19,7 +19,7 @@ class NamespaceStatistics < ApplicationRecord ...@@ -19,7 +19,7 @@ class NamespaceStatistics < ApplicationRecord
COLUMNS_TO_REFRESH = [:wiki_size].freeze COLUMNS_TO_REFRESH = [:wiki_size].freeze
def refresh!(only: []) def refresh!(only: [])
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
return unless group? return unless group?
COLUMNS_TO_REFRESH.each do |column| COLUMNS_TO_REFRESH.each do |column|
......
...@@ -133,7 +133,7 @@ module EE ...@@ -133,7 +133,7 @@ module EE
# @return [AuditEvent, nil] if record is persisted or nil if audit events # @return [AuditEvent, nil] if record is persisted or nil if audit events
# features are not enabled # features are not enabled
def unauth_security_event def unauth_security_event
return unless audit_events_enabled? && ::Gitlab::Database.main.read_write? return unless audit_events_enabled? && ::Gitlab::Database.read_write?
add_security_event_admin_details! add_security_event_admin_details!
......
...@@ -15,7 +15,7 @@ module Geo ...@@ -15,7 +15,7 @@ module Geo
end end
def execute def execute
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
try_obtain_lease do try_obtain_lease do
log_info('Prune Geo Event Log entries up to id', geo_event_log_id: event_log_min_id) log_info('Prune Geo Event Log entries up to id', geo_event_log_id: event_log_min_id)
......
...@@ -46,7 +46,7 @@ module EE ...@@ -46,7 +46,7 @@ module EE
end end
def audit_push?(project) def audit_push?(project)
project.push_audit_events_enabled? && !::Gitlab::Database.main.read_only? project.push_audit_events_enabled? && !::Gitlab::Database.read_only?
end end
end end
end end
...@@ -16,7 +16,7 @@ module Geo ...@@ -16,7 +16,7 @@ module Geo
tags :exclude_from_gitlab_com tags :exclude_from_gitlab_com
def perform def perform
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
return unless Gitlab::Database.main.healthy? return unless Gitlab::Database.main.healthy?
unless ::GeoNode.secondary_nodes.any? unless ::GeoNode.secondary_nodes.any?
......
...@@ -18,7 +18,7 @@ class ProjectImportScheduleWorker ...@@ -18,7 +18,7 @@ class ProjectImportScheduleWorker
tags :needs_own_queue tags :needs_own_queue
def perform(project_id) def perform(project_id)
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
project = Project.with_route.with_import_state.with_namespace.find_by_id(project_id) project = Project.with_route.with_import_state.with_namespace.find_by_id(project_id)
raise ImportStateNotFound unless project&.import_state raise ImportStateNotFound unless project&.import_state
......
...@@ -14,7 +14,7 @@ class UpdateAllMirrorsWorker # rubocop:disable Scalability/IdempotentWorker ...@@ -14,7 +14,7 @@ class UpdateAllMirrorsWorker # rubocop:disable Scalability/IdempotentWorker
RESCHEDULE_WAIT = 1.second RESCHEDULE_WAIT = 1.second
def perform def perform
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
scheduled = 0 scheduled = 0
with_lease do with_lease do
......
...@@ -12,7 +12,7 @@ class UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker # rubocop:disable Scalab ...@@ -12,7 +12,7 @@ class UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker # rubocop:disable Scalab
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def perform def perform
return if ::Gitlab::Database.main.read_only? return if ::Gitlab::Database.read_only?
return unless ::Gitlab::CurrentSettings.should_check_namespace_plan? return unless ::Gitlab::CurrentSettings.should_check_namespace_plan?
GitlabSubscription.with_a_paid_hosted_plan.preload_for_refresh_seat.find_in_batches(batch_size: 100) do |subscriptions| GitlabSubscription.with_a_paid_hosted_plan.preload_for_refresh_seat.find_in_batches(batch_size: 100) do |subscriptions|
......
...@@ -10,7 +10,7 @@ module EE ...@@ -10,7 +10,7 @@ module EE
override :update_user override :update_user
def update_user def update_user
return if ::Gitlab::Database.main.read_only? return if ::Gitlab::Database.read_only?
update_user_attributes update_user_attributes
update_memberships update_memberships
......
...@@ -61,7 +61,7 @@ module EE ...@@ -61,7 +61,7 @@ module EE
override :perform override :perform
def perform(table_name = EVENT_TABLES.first) def perform(table_name = EVENT_TABLES.first)
return if ::Gitlab::Database.main.read_only? return if ::Gitlab::Database.read_only?
deleted_rows = prune_orphaned_rows(table_name) deleted_rows = prune_orphaned_rows(table_name)
table_name = next_table(table_name) if deleted_rows == 0 table_name = next_table(table_name) if deleted_rows == 0
......
# frozen_string_literal: true
module EE
module Gitlab
module Database
extend ActiveSupport::Concern
class_methods do
extend ::Gitlab::Utils::Override
override :read_only?
def read_only?
::Gitlab::Geo.secondary? || ::Gitlab.maintenance_mode?
end
end
end
end
end
...@@ -5,12 +5,6 @@ module EE ...@@ -5,12 +5,6 @@ module EE
module Database module Database
module Connection module Connection
extend ActiveSupport::Concern extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
override :read_only?
def read_only?
::Gitlab::Geo.secondary? || ::Gitlab.maintenance_mode?
end
def healthy? def healthy?
!Postgresql::ReplicationSlot.lag_too_great? !Postgresql::ReplicationSlot.lag_too_great?
......
...@@ -25,7 +25,7 @@ module EE ...@@ -25,7 +25,7 @@ module EE
end end
def geo_custom_action? def geo_custom_action?
return unless ::Gitlab::Database.main.read_only? return unless ::Gitlab::Database.read_only?
return unless ::Gitlab::Geo.secondary_with_primary? return unless ::Gitlab::Geo.secondary_with_primary?
receive_pack? || upload_pack_and_not_replicated? receive_pack? || upload_pack_and_not_replicated?
...@@ -55,7 +55,7 @@ module EE ...@@ -55,7 +55,7 @@ module EE
end end
def current_replication_lag_message def current_replication_lag_message
return if ::Gitlab::Database.main.read_write? || current_replication_lag == 0 return if ::Gitlab::Database.read_write? || current_replication_lag == 0
"Current replication lag: #{current_replication_lag} seconds" "Current replication lag: #{current_replication_lag} seconds"
end end
......
...@@ -10,7 +10,7 @@ RSpec.describe ApplicationHelper do ...@@ -10,7 +10,7 @@ RSpec.describe ApplicationHelper do
context 'when not in a Geo secondary' do context 'when not in a Geo secondary' do
it 'returns a fallback message if database is readonly' do it 'returns a fallback message if database is readonly' do
expect(Gitlab::Database.main).to receive(:read_only?) { true } expect(Gitlab::Database).to receive(:read_only?) { true }
expect(helper.read_only_message).to match('You are on a read-only GitLab instance') expect(helper.read_only_message).to match('You are on a read-only GitLab instance')
end end
...@@ -38,7 +38,7 @@ RSpec.describe ApplicationHelper do ...@@ -38,7 +38,7 @@ RSpec.describe ApplicationHelper do
context 'when database is read-only' do context 'when database is read-only' do
it 'stacks read-only and maintenance mode messages' do it 'stacks read-only and maintenance mode messages' do
expect(Gitlab::Database.main).to receive(:read_only?).twice { true } expect(Gitlab::Database).to receive(:read_only?).twice { true }
expect(helper.read_only_message).to match('You are on a read-only GitLab instance') expect(helper.read_only_message).to match('You are on a read-only GitLab instance')
expect(helper.read_only_message).to match(/#{default_maintenance_mode_message}/) expect(helper.read_only_message).to match(/#{default_maintenance_mode_message}/)
......
...@@ -49,7 +49,7 @@ RSpec.describe Gitlab::BackgroundMigration::PruneOrphanedGeoEvents, geo: false, ...@@ -49,7 +49,7 @@ RSpec.describe Gitlab::BackgroundMigration::PruneOrphanedGeoEvents, geo: false,
end end
it 'does nothing if the database is read-only' do it 'does nothing if the database is read-only' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect { background_migration.perform(event_table_name) }.not_to change { Geo::RepositoryUpdatedEvent.count } expect { background_migration.perform(event_table_name) }.not_to change { Geo::RepositoryUpdatedEvent.count }
end end
......
...@@ -7,47 +7,6 @@ RSpec.describe Gitlab::Database::Connection do ...@@ -7,47 +7,6 @@ RSpec.describe Gitlab::Database::Connection do
let(:connection) { described_class.new } let(:connection) { described_class.new }
describe '#read_only?' do
context 'with Geo enabled' do
before do
allow(Gitlab::Geo).to receive(:enabled?) { true }
allow(Gitlab::Geo).to receive(:current_node) { geo_node }
end
context 'is Geo secondary node' do
let(:geo_node) { create(:geo_node) }
it 'returns true' do
expect(connection.read_only?).to be_truthy
end
end
context 'is Geo primary node' do
let(:geo_node) { create(:geo_node, :primary) }
it 'returns false when is Geo primary node' do
expect(connection.read_only?).to be_falsey
end
end
end
context 'with Geo disabled' do
it 'returns false' do
expect(connection.read_only?).to be_falsey
end
end
context 'in maintenance mode' do
before do
stub_maintenance_mode_setting(true)
end
it 'returns true' do
expect(connection.read_only?).to be_truthy
end
end
end
describe '#healthy?' do describe '#healthy?' do
it 'returns true when replication lag is not too great' do it 'returns true when replication lag is not too great' do
allow(Postgresql::ReplicationSlot).to receive(:lag_too_great?).and_return(false) allow(Postgresql::ReplicationSlot).to receive(:lag_too_great?).and_return(false)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database do
include ::EE::GeoHelpers
describe '.read_only?' do
context 'with Geo enabled' do
before do
allow(Gitlab::Geo).to receive(:enabled?) { true }
allow(Gitlab::Geo).to receive(:current_node) { geo_node }
end
context 'is Geo secondary node' do
let(:geo_node) { create(:geo_node) }
it 'returns true' do
expect(described_class.read_only?).to be_truthy
end
end
context 'is Geo primary node' do
let(:geo_node) { create(:geo_node, :primary) }
it 'returns false when is Geo primary node' do
expect(described_class.read_only?).to be_falsey
end
end
end
context 'with Geo disabled' do
it 'returns false' do
expect(described_class.read_only?).to be_falsey
end
end
context 'in maintenance mode' do
before do
stub_maintenance_mode_setting(true)
end
it 'returns true' do
expect(described_class.read_only?).to be_truthy
end
end
end
end
...@@ -51,7 +51,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -51,7 +51,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not block user in GitLab' do it 'does not block user in GitLab' do
...@@ -76,7 +76,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -76,7 +76,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not unblock user in GitLab' do it 'does not unblock user in GitLab' do
...@@ -102,7 +102,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -102,7 +102,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not block user in GitLab' do it 'does not block user in GitLab' do
...@@ -145,7 +145,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -145,7 +145,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it 'does not update the email when in a read-only GitLab instance' do it 'does not update the email when in a read-only GitLab instance' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect { access.update_user }.not_to change(user, :email) expect { access.update_user }.not_to change(user, :email)
end end
...@@ -181,7 +181,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -181,7 +181,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it 'does not update the name when in a read-only GitLab instance' do it 'does not update the name when in a read-only GitLab instance' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect { access.update_user }.not_to change(user, :name) expect { access.update_user }.not_to change(user, :name)
end end
...@@ -202,7 +202,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -202,7 +202,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it 'does not update the name when in a read-only GitLab instance' do it 'does not update the name when in a read-only GitLab instance' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect { access.update_user }.not_to change(user, :name) expect { access.update_user }.not_to change(user, :name)
end end
...@@ -240,7 +240,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -240,7 +240,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it "doesn't trigger a sync when in a read-only GitLab instance" do it "doesn't trigger a sync when in a read-only GitLab instance" do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
create(:ldap_group_link, cn: 'Group1', provider: provider) create(:ldap_group_link, cn: 'Group1', provider: provider)
create(:ldap_group_link, cn: 'Group2', provider: provider) create(:ldap_group_link, cn: 'Group2', provider: provider)
...@@ -313,7 +313,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -313,7 +313,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it 'does not add a SSH key when in a read-only GitLab instance' do it 'does not add a SSH key when in a read-only GitLab instance' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
stub_ldap_person_find_by_dn(entry, provider) stub_ldap_person_find_by_dn(entry, provider)
expect { access.update_user }.not_to change(user.keys, :count) expect { access.update_user }.not_to change(user.keys, :count)
...@@ -377,7 +377,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -377,7 +377,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it 'does not add a Kerberos identity when in a read-only GitLab instance' do it 'does not add a Kerberos identity when in a read-only GitLab instance' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
allow_any_instance_of(EE::Gitlab::Auth::Ldap::Person).to receive_messages(kerberos_principal: 'mylogin@FOO.COM') allow_any_instance_of(EE::Gitlab::Auth::Ldap::Person).to receive_messages(kerberos_principal: 'mylogin@FOO.COM')
expect { access.update_user }.not_to change(user.identities.where(provider: :kerberos), :count) expect { access.update_user }.not_to change(user.identities.where(provider: :kerberos), :count)
...@@ -398,7 +398,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -398,7 +398,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it 'does not update the external UID when in a read-only GitLab instance' do it 'does not update the external UID when in a read-only GitLab instance' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
access.update_user access.update_user
......
...@@ -32,7 +32,7 @@ RSpec.describe Gitlab::GitAccess do ...@@ -32,7 +32,7 @@ RSpec.describe Gitlab::GitAccess do
context "when in a read-only GitLab instance" do context "when in a read-only GitLab instance" do
before do before do
create(:protected_branch, name: 'feature', project: project) create(:protected_branch, name: 'feature', project: project)
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
let(:primary_repo_url) { geo_primary_http_url_to_repo(project) } let(:primary_repo_url) { geo_primary_http_url_to_repo(project) }
......
...@@ -40,7 +40,7 @@ RSpec.describe Gitlab::GitAccessWiki do ...@@ -40,7 +40,7 @@ RSpec.describe Gitlab::GitAccessWiki do
context 'when in a read-only GitLab instance' do context 'when in a read-only GitLab instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
it 'does not give access to upload wiki code' do it 'does not give access to upload wiki code' do
...@@ -153,7 +153,7 @@ RSpec.describe Gitlab::GitAccessWiki do ...@@ -153,7 +153,7 @@ RSpec.describe Gitlab::GitAccessWiki do
before do before do
create(:protected_branch, name: 'feature', project: project) create(:protected_branch, name: 'feature', project: project)
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
let(:primary_repo_url) { geo_primary_http_url_to_repo(project.wiki) } let(:primary_repo_url) { geo_primary_http_url_to_repo(project.wiki) }
......
...@@ -840,7 +840,7 @@ RSpec.describe Group do ...@@ -840,7 +840,7 @@ RSpec.describe Group do
context 'in read-only mode' do context 'in read-only mode' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
allow(group).to receive(:create_or_update).and_raise(ActiveRecord::ReadOnlyRecord) allow(group).to receive(:create_or_update).and_raise(ActiveRecord::ReadOnlyRecord)
end end
......
...@@ -121,7 +121,7 @@ RSpec.describe Namespace do ...@@ -121,7 +121,7 @@ RSpec.describe Namespace do
context 'when DB is read-only' do context 'when DB is read-only' do
before do before do
expect(Gitlab::Database.main).to receive(:read_only?) { true } expect(Gitlab::Database).to receive(:read_only?) { true }
end end
it 'returns free plan' do it 'returns free plan' do
......
...@@ -287,7 +287,7 @@ RSpec.describe User do ...@@ -287,7 +287,7 @@ RSpec.describe User do
end end
it 'does not clear remember_created_at when in a GitLab read-only instance' do it 'does not clear remember_created_at when in a GitLab read-only instance' do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
expect { subject.forget_me! }.not_to change(subject, :remember_created_at) expect { subject.forget_me! }.not_to change(subject, :remember_created_at)
end end
...@@ -303,7 +303,7 @@ RSpec.describe User do ...@@ -303,7 +303,7 @@ RSpec.describe User do
end end
it 'does not update remember_created_at when in a Geo read-only instance' do it 'does not update remember_created_at when in a Geo read-only instance' do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
expect { subject.remember_me! }.not_to change(subject, :remember_created_at) expect { subject.remember_me! }.not_to change(subject, :remember_created_at)
end end
......
...@@ -26,7 +26,7 @@ RSpec.describe NamespaceStatistics do ...@@ -26,7 +26,7 @@ RSpec.describe NamespaceStatistics do
context 'when database is read_only' do context 'when database is read_only' do
it 'does not save the object' do it 'does not save the object' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect(statistics).not_to receive(:save!) expect(statistics).not_to receive(:save!)
......
...@@ -92,7 +92,7 @@ RSpec.describe AuditEventService, :request_store do ...@@ -92,7 +92,7 @@ RSpec.describe AuditEventService, :request_store do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not create an event' do it 'does not create an event' do
...@@ -336,7 +336,7 @@ RSpec.describe AuditEventService, :request_store do ...@@ -336,7 +336,7 @@ RSpec.describe AuditEventService, :request_store do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not create an event record in the database' do it 'does not create an event record in the database' do
......
...@@ -7,7 +7,7 @@ RSpec.describe Keys::LastUsedService do ...@@ -7,7 +7,7 @@ RSpec.describe Keys::LastUsedService do
key = create(:key, last_used_at: 1.year.ago) key = create(:key, last_used_at: 1.year.ago)
original_time = key.last_used_at original_time = key.last_used_at
allow(::Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(::Gitlab::Database).to receive(:read_only?).and_return(true)
described_class.new(key).execute described_class.new(key).execute
expect(key.reload.last_used_at).to be_like_time(original_time) expect(key.reload.last_used_at).to be_like_time(original_time)
......
...@@ -33,7 +33,7 @@ RSpec.describe PostReceive do ...@@ -33,7 +33,7 @@ RSpec.describe PostReceive do
context 'when DB is readonly' do context 'when DB is readonly' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
it 'does not call RepositoryPushAuditEventWorker' do it 'does not call RepositoryPushAuditEventWorker' do
...@@ -45,7 +45,7 @@ RSpec.describe PostReceive do ...@@ -45,7 +45,7 @@ RSpec.describe PostReceive do
context 'when DB is not readonly' do context 'when DB is not readonly' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { false } allow(Gitlab::Database).to receive(:read_only?) { false }
end end
it 'calls RepositoryPushAuditEventWorker' do it 'calls RepositoryPushAuditEventWorker' do
......
...@@ -17,7 +17,7 @@ RSpec.describe ProjectImportScheduleWorker do ...@@ -17,7 +17,7 @@ RSpec.describe ProjectImportScheduleWorker do
end end
it 'does nothing if the database is read-only' do it 'does nothing if the database is read-only' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect(ProjectImportState).not_to receive(:project_id).with(project_id: project.id) expect(ProjectImportState).not_to receive(:project_id).with(project_id: project.id)
subject subject
......
...@@ -18,7 +18,7 @@ RSpec.describe UpdateAllMirrorsWorker do ...@@ -18,7 +18,7 @@ RSpec.describe UpdateAllMirrorsWorker do
describe '#perform' do describe '#perform' do
it 'does nothing if the database is read-only' do it 'does nothing if the database is read-only' do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect(worker).not_to receive(:schedule_mirrors!) expect(worker).not_to receive(:schedule_mirrors!)
worker.perform worker.perform
......
...@@ -14,7 +14,7 @@ RSpec.describe UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker do ...@@ -14,7 +14,7 @@ RSpec.describe UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker do
let(:subscription_attrs) { nil } let(:subscription_attrs) { nil }
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { db_is_read_only } allow(Gitlab::Database).to receive(:read_only?) { db_is_read_only }
allow(Gitlab::CurrentSettings).to receive(:should_check_namespace_plan?) { true } allow(Gitlab::CurrentSettings).to receive(:should_check_namespace_plan?) { true }
end end
......
...@@ -42,7 +42,7 @@ module API ...@@ -42,7 +42,7 @@ module API
def update_project_feature_usage_for(project) def update_project_feature_usage_for(project)
# Prevent errors on GitLab Geo not allowing # Prevent errors on GitLab Geo not allowing
# UPDATE statements to happen in GET requests. # UPDATE statements to happen in GET requests.
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
project.log_jira_dvcs_integration_usage(cloud: jira_cloud?) project.log_jira_dvcs_integration_usage(cloud: jira_cloud?)
end end
......
...@@ -394,7 +394,7 @@ module Gitlab ...@@ -394,7 +394,7 @@ module Gitlab
end end
def user_auth_attempt!(user, success:) def user_auth_attempt!(user, success:)
return unless user && Gitlab::Database.main.read_write? return unless user && Gitlab::Database.read_write?
return user.unlock_access! if success return user.unlock_access! if success
user.increment_failed_attempts! user.increment_failed_attempts!
......
...@@ -21,7 +21,7 @@ module Gitlab ...@@ -21,7 +21,7 @@ module Gitlab
# Whether user is allowed, or not, we should update # Whether user is allowed, or not, we should update
# permissions to keep things clean # permissions to keep things clean
if access.allowed? if access.allowed?
unless Gitlab::Database.main.read_only? unless Gitlab::Database.read_only?
access.update_user access.update_user
Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute
end end
......
...@@ -173,6 +173,14 @@ module Gitlab ...@@ -173,6 +173,14 @@ module Gitlab
ActiveRecord::Base.prepend(ActiveRecordBaseTransactionMetrics) ActiveRecord::Base.prepend(ActiveRecordBaseTransactionMetrics)
end end
def self.read_only?
false
end
def self.read_write?
!read_only?
end
# MonkeyPatch for ActiveRecord::Base for adding observability # MonkeyPatch for ActiveRecord::Base for adding observability
module ActiveRecordBaseTransactionMetrics module ActiveRecordBaseTransactionMetrics
extend ActiveSupport::Concern extend ActiveSupport::Concern
...@@ -189,3 +197,5 @@ module Gitlab ...@@ -189,3 +197,5 @@ module Gitlab
end end
end end
end end
Gitlab::Database.prepend_mod_with('Gitlab::Database')
...@@ -80,14 +80,6 @@ module Gitlab ...@@ -80,14 +80,6 @@ module Gitlab
scope.establish_connection(config.merge(prepared_statements: false)) scope.establish_connection(config.merge(prepared_statements: false))
end end
def read_only?
false
end
def read_write?
!read_only?
end
# Check whether the underlying database is in read-only mode # Check whether the underlying database is in read-only mode
def db_read_only? def db_read_only?
pg_is_in_recovery = pg_is_in_recovery =
......
...@@ -257,7 +257,7 @@ module Gitlab ...@@ -257,7 +257,7 @@ module Gitlab
def check_db_accessibility! def check_db_accessibility!
return unless receive_pack? return unless receive_pack?
if Gitlab::Database.main.read_only? if Gitlab::Database.read_only?
raise ForbiddenError, push_to_read_only_message raise ForbiddenError, push_to_read_only_message
end end
end end
......
...@@ -71,7 +71,7 @@ module Gitlab ...@@ -71,7 +71,7 @@ module Gitlab
def create_cached_signature! def create_cached_signature!
using_keychain do |gpg_key| using_keychain do |gpg_key|
attributes = attributes(gpg_key) attributes = attributes(gpg_key)
break GpgSignature.new(attributes) if Gitlab::Database.main.read_only? break GpgSignature.new(attributes) if Gitlab::Database.read_only?
GpgSignature.safe_create!(attributes) GpgSignature.safe_create!(attributes)
end end
......
...@@ -71,7 +71,7 @@ module Gitlab ...@@ -71,7 +71,7 @@ module Gitlab
end end
def generate_private_key def generate_private_key
return if Gitlab::Database.main.read_only? return if Gitlab::Database.read_only?
application_settings = Gitlab::CurrentSettings.current_application_settings application_settings = Gitlab::CurrentSettings.current_application_settings
application_settings.with_lock do application_settings.with_lock do
......
...@@ -38,7 +38,7 @@ module Gitlab ...@@ -38,7 +38,7 @@ module Gitlab
end end
def save_markdown(updates) def save_markdown(updates)
return unless persisted? && Gitlab::Database.main.read_write? return unless persisted? && Gitlab::Database.read_write?
update_columns(updates) update_columns(updates)
end end
......
...@@ -59,7 +59,7 @@ module Gitlab ...@@ -59,7 +59,7 @@ module Gitlab
# Overridden in EE module # Overridden in EE module
def read_only? def read_only?
Gitlab::Database.main.read_only? Gitlab::Database.read_only?
end end
def json_request? def json_request?
......
...@@ -49,7 +49,7 @@ module Gitlab ...@@ -49,7 +49,7 @@ module Gitlab
def create_cached_signature! def create_cached_signature!
return if attributes.nil? return if attributes.nil?
return X509CommitSignature.new(attributes) if Gitlab::Database.main.read_only? return X509CommitSignature.new(attributes) if Gitlab::Database.read_only?
X509CommitSignature.safe_create!(attributes) X509CommitSignature.safe_create!(attributes)
end end
......
...@@ -4,7 +4,7 @@ namespace :gitlab do ...@@ -4,7 +4,7 @@ namespace :gitlab do
namespace :storage do namespace :storage do
desc 'GitLab | Storage | Migrate existing projects to Hashed Storage' desc 'GitLab | Storage | Migrate existing projects to Hashed Storage'
task migrate_to_hashed: :environment do task migrate_to_hashed: :environment do
if Gitlab::Database.main.read_only? if Gitlab::Database.read_only?
abort 'This task requires database write access. Exiting.' abort 'This task requires database write access. Exiting.'
end end
...@@ -50,7 +50,7 @@ namespace :gitlab do ...@@ -50,7 +50,7 @@ namespace :gitlab do
desc 'GitLab | Storage | Rollback existing projects to Legacy Storage' desc 'GitLab | Storage | Rollback existing projects to Legacy Storage'
task rollback_to_legacy: :environment do task rollback_to_legacy: :environment do
if Gitlab::Database.main.read_only? if Gitlab::Database.read_only?
abort 'This task requires database write access. Exiting.' abort 'This task requires database write access. Exiting.'
end end
......
...@@ -179,7 +179,7 @@ RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do ...@@ -179,7 +179,7 @@ RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not attempt to write to the database with valid otp' do it 'does not attempt to write to the database with valid otp' do
......
...@@ -24,7 +24,7 @@ RSpec.describe Repositories::GitHttpController do ...@@ -24,7 +24,7 @@ RSpec.describe Repositories::GitHttpController do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not update project statistics' do it 'does not update project statistics' do
......
...@@ -37,7 +37,7 @@ RSpec.describe 'Admin Mode Logout', :js do ...@@ -37,7 +37,7 @@ RSpec.describe 'Admin Mode Logout', :js do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'disable removes admin mode and redirects to root page' do it 'disable removes admin mode and redirects to root page' do
......
...@@ -57,7 +57,7 @@ RSpec.describe 'Admin mode', :js do ...@@ -57,7 +57,7 @@ RSpec.describe 'Admin mode', :js do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'can enter admin mode' do it 'can enter admin mode' do
...@@ -117,7 +117,7 @@ RSpec.describe 'Admin mode', :js do ...@@ -117,7 +117,7 @@ RSpec.describe 'Admin mode', :js do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'can leave admin mode' do it 'can leave admin mode' do
......
...@@ -315,7 +315,7 @@ RSpec.describe 'Branches' do ...@@ -315,7 +315,7 @@ RSpec.describe 'Branches' do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it_behaves_like 'compares branches' it_behaves_like 'compares branches'
......
...@@ -40,7 +40,7 @@ RSpec.describe "Compare", :js do ...@@ -40,7 +40,7 @@ RSpec.describe "Compare", :js do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it_behaves_like 'compares branches' it_behaves_like 'compares branches'
......
...@@ -11,7 +11,7 @@ RSpec.describe 'read-only message' do ...@@ -11,7 +11,7 @@ RSpec.describe 'read-only message' do
context 'when database is read-only' do context 'when database is read-only' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it_behaves_like 'Read-only instance', /You are on a read\-only GitLab instance./ it_behaves_like 'Read-only instance', /You are on a read\-only GitLab instance./
...@@ -19,7 +19,7 @@ RSpec.describe 'read-only message' do ...@@ -19,7 +19,7 @@ RSpec.describe 'read-only message' do
context 'when database is in read-write mode' do context 'when database is in read-write mode' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(false) allow(Gitlab::Database).to receive(:read_only?).and_return(false)
end end
it_behaves_like 'Read-write instance', /You are on a read\-only GitLab instance./ it_behaves_like 'Read-write instance', /You are on a read\-only GitLab instance./
......
...@@ -24,7 +24,7 @@ RSpec.describe 'Logout/Sign out', :js do ...@@ -24,7 +24,7 @@ RSpec.describe 'Logout/Sign out', :js do
context 'on a read-only instance' do context 'on a read-only instance' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'sign out redirects to sign in page' do it 'sign out redirects to sign in page' do
......
...@@ -65,7 +65,7 @@ RSpec.describe Banzai::Renderer do ...@@ -65,7 +65,7 @@ RSpec.describe Banzai::Renderer do
end end
it "skips database caching on a GitLab read-only instance" do it "skips database caching on a GitLab read-only instance" do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect(object).to receive(:refresh_markdown_cache!) expect(object).to receive(:refresh_markdown_cache!)
is_expected.to eq('field_html') is_expected.to eq('field_html')
......
...@@ -22,7 +22,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do ...@@ -22,7 +22,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end end
it "does not update user's `last_credential_check_at` when in a read-only GitLab instance" do it "does not update user's `last_credential_check_at` when in a read-only GitLab instance" do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
expect { described_class.allowed?(user) } expect { described_class.allowed?(user) }
.not_to change { user.last_credential_check_at } .not_to change { user.last_credential_check_at }
......
...@@ -844,7 +844,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do ...@@ -844,7 +844,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when the database is read-only' do context 'when the database is read-only' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not increment failed_attempts when true and password is incorrect' do it 'does not increment failed_attempts when true and password is incorrect' do
......
...@@ -162,18 +162,6 @@ RSpec.describe Gitlab::Database::Connection do ...@@ -162,18 +162,6 @@ RSpec.describe Gitlab::Database::Connection do
end end
end end
describe '#read_only?' do
it 'returns false' do
expect(connection.read_only?).to eq(false)
end
end
describe '#read_write' do
it 'returns true' do
expect(connection.read_write?).to eq(true)
end
end
describe '#db_read_only?' do describe '#db_read_only?' do
it 'detects a read-only database' do it 'detects a read-only database' do
allow(connection.scope.connection) allow(connection.scope.connection)
......
...@@ -190,6 +190,18 @@ RSpec.describe Gitlab::Database do ...@@ -190,6 +190,18 @@ RSpec.describe Gitlab::Database do
end end
end end
describe '.read_only?' do
it 'returns false' do
expect(described_class.read_only?).to eq(false)
end
end
describe '.read_write' do
it 'returns true' do
expect(described_class.read_write?).to eq(true)
end
end
describe 'ActiveRecordBaseTransactionMetrics' do describe 'ActiveRecordBaseTransactionMetrics' do
def subscribe_events def subscribe_events
events = [] events = []
......
...@@ -392,7 +392,7 @@ RSpec.describe Gitlab::GitAccess do ...@@ -392,7 +392,7 @@ RSpec.describe Gitlab::GitAccess do
context 'when in a read-only GitLab instance' do context 'when in a read-only GitLab instance' do
before do before do
create(:protected_branch, name: 'feature', project: project) create(:protected_branch, name: 'feature', project: project)
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
it { expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:cannot_push_to_read_only]) } it { expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:cannot_push_to_read_only]) }
......
...@@ -31,7 +31,7 @@ RSpec.describe Gitlab::GitAccessWiki do ...@@ -31,7 +31,7 @@ RSpec.describe Gitlab::GitAccessWiki do
let(:message) { "You can't push code to a read-only GitLab instance." } let(:message) { "You can't push code to a read-only GitLab instance." }
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
it_behaves_like 'forbidden git access' it_behaves_like 'forbidden git access'
......
...@@ -91,7 +91,7 @@ RSpec.describe Gitlab::Gpg::Commit do ...@@ -91,7 +91,7 @@ RSpec.describe Gitlab::Gpg::Commit do
context 'read-only mode' do context 'read-only mode' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end end
it 'does not create a cached signature' do it 'does not create a cached signature' do
......
...@@ -5,7 +5,7 @@ require 'spec_helper' ...@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Middleware::ReadOnly do RSpec.describe Gitlab::Middleware::ReadOnly do
context 'when database is read-only' do context 'when database is read-only' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
it_behaves_like 'write access for a read-only GitLab instance' it_behaves_like 'write access for a read-only GitLab instance'
......
...@@ -99,7 +99,7 @@ RSpec.describe DeprecatedAssignee do ...@@ -99,7 +99,7 @@ RSpec.describe DeprecatedAssignee do
context 'when DB is read-only' do context 'when DB is read-only' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
it 'returns a users relation' do it 'returns a users relation' do
...@@ -139,7 +139,7 @@ RSpec.describe DeprecatedAssignee do ...@@ -139,7 +139,7 @@ RSpec.describe DeprecatedAssignee do
context 'when DB is read-only' do context 'when DB is read-only' do
before do before do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
end end
it 'returns a list of user IDs' do it 'returns a list of user IDs' do
......
...@@ -214,7 +214,7 @@ RSpec.describe ProjectStatistics do ...@@ -214,7 +214,7 @@ RSpec.describe ProjectStatistics do
context 'when the database is read-only' do context 'when the database is read-only' do
it 'does nothing' do it 'does nothing' do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
expect(statistics).not_to receive(:update_commit_count) expect(statistics).not_to receive(:update_commit_count)
expect(statistics).not_to receive(:update_repository_size) expect(statistics).not_to receive(:update_repository_size)
......
...@@ -86,7 +86,7 @@ RSpec.describe SnippetStatistics do ...@@ -86,7 +86,7 @@ RSpec.describe SnippetStatistics do
context 'when the database is read-only' do context 'when the database is read-only' do
it 'does nothing' do it 'does nothing' do
allow(Gitlab::Database.main).to receive(:read_only?) { true } allow(Gitlab::Database).to receive(:read_only?) { true }
expect(statistics).not_to receive(:update_commit_count) expect(statistics).not_to receive(:update_commit_count)
expect(statistics).not_to receive(:update_file_count) expect(statistics).not_to receive(:update_file_count)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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