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
::Users::ValidateOtpService.new(user).execute(user_params[:otp_attempt])
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])
end
......
......@@ -27,7 +27,7 @@ module Boards
list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params)
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)
end
......
......@@ -47,7 +47,7 @@ module AuthenticatesWithTwoFactorForAdminMode
# Remove any lingering user data from login
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
enable_admin_mode
......
......@@ -148,7 +148,7 @@ module IssuableActions
# on GET requests.
# 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
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)
else
notes_filter = current_user&.set_notes_filter(notes_filter_param, issuable) || notes_filter_param
......
......@@ -17,7 +17,7 @@ module RecordUserLastActivity
def set_user_last_activity
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
Users::ActivityService.new(current_user).execute
......
......@@ -41,7 +41,7 @@ module SortingPreference
sort_param = params[:sort]
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
user_preference.update(field => sort_param)
......
......@@ -77,7 +77,7 @@ module Repositories
def update_fetch_statistics
return unless project
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
return unless repo_type.project?
OnboardingProgressService.async(project.namespace_id).execute(action: :git_pull)
......
......@@ -126,7 +126,7 @@ module Repositories
# Overridden in EE
def batch_operation_disallowed?
upload_request? && Gitlab::Database.main.read_only?
upload_request? && Gitlab::Database.read_only?
end
# Overridden in EE
......
......@@ -29,7 +29,7 @@ module Mutations
end
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
.reject { |arg| arg.accepts?(args.fetch(arg.keyword, :not_given)) }
......
......@@ -344,7 +344,7 @@ module ApplicationHelper
# Overridden in EE
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.')
end
......
......@@ -34,7 +34,7 @@ module DeprecatedAssignee
end
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)
end
......@@ -43,7 +43,7 @@ module DeprecatedAssignee
end
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)
end
......@@ -56,7 +56,7 @@ module DeprecatedAssignee
# This will make the background migration process quicker (#26496) as it'll have less
# assignee_id rows to look through.
def nullify_deprecated_assignee
return unless persisted? && Gitlab::Database.main.read_only?
return unless persisted? && Gitlab::Database.read_only?
update_column(:assignee_id, nil)
end
......
......@@ -41,7 +41,7 @@ module TokenAuthenticatableStrategies
# Resets the token, but only saves when the database is in read & write mode
def reset_token!(instance)
write_new_token(instance)
instance.save! if Gitlab::Database.main.read_write?
instance.save! if Gitlab::Database.read_write?
end
def self.fabricate(model, field, options)
......
......@@ -2818,11 +2818,11 @@ class Project < ApplicationRecord
end
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
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
def active_runners_with_tags
......
......@@ -38,7 +38,7 @@ class ProjectStatistics < ApplicationRecord
end
def refresh!(only: [])
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
COLUMNS_TO_REFRESH.each do |column, generator|
if only.empty? || only.include?(column)
......
......@@ -34,7 +34,7 @@ class SnippetStatistics < ApplicationRecord
end
def refresh!
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
update_commit_count
update_repository_size
......
......@@ -80,7 +80,7 @@ class User < ApplicationRecord
# to limit database writes to at most once every hour
# rubocop: disable CodeReuse/ServiceClass
def update_tracked_fields!(request)
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
update_tracked_fields(request)
......@@ -363,7 +363,7 @@ class User < ApplicationRecord
end
before_transition do
!Gitlab::Database.main.read_only?
!Gitlab::Database.read_only?
end
# rubocop: disable CodeReuse/ServiceClass
......@@ -848,11 +848,11 @@ class User < ApplicationRecord
end
def remember_me!
super if ::Gitlab::Database.main.read_write?
super if ::Gitlab::Database.read_write?
end
def forget_me!
super if ::Gitlab::Database.main.read_write?
super if ::Gitlab::Database.read_write?
end
def disable_two_factor!
......@@ -1751,7 +1751,7 @@ class User < ApplicationRecord
#
# rubocop: disable CodeReuse/ServiceClass
def increment_failed_attempts!
return if ::Gitlab::Database.main.read_only?
return if ::Gitlab::Database.read_only?
increment_failed_attempts
......@@ -1995,7 +1995,7 @@ class User < ApplicationRecord
def consume_otp!
if 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
false
......
......@@ -111,7 +111,7 @@ class AuditEventService
end
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))
save_or_track event
......@@ -120,7 +120,7 @@ class AuditEventService
end
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)
save_or_track event
......
......@@ -4,7 +4,7 @@ module Boards
module Visits
class CreateService < Boards::BaseService
def execute(board)
return unless current_user && Gitlab::Database.main.read_write?
return unless current_user && Gitlab::Database.read_write?
return unless board
model.visited!(current_user, board)
......
......@@ -18,7 +18,7 @@ module Keys
end
def update?
return false if ::Gitlab::Database.main.read_only?
return false if ::Gitlab::Database.read_only?
last_used = key.last_used_at
......
......@@ -166,7 +166,7 @@ module MergeRequests
strong_memoize(:service_error) do
if !merge_request
ServiceResponse.error(message: 'Invalid argument')
elsif Gitlab::Database.main.read_only?
elsif Gitlab::Database.read_only?
ServiceResponse.error(message: 'Unsupported operation')
end
end
......
......@@ -11,7 +11,7 @@ module Packages
::Gitlab::UsageDataCounters::PackageEventCounter.count(event_name)
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!(
event_type: event_name,
originator: current_user&.id,
......
......@@ -18,7 +18,7 @@ module PersonalAccessTokens
private
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
......
......@@ -19,7 +19,7 @@ class Repositories::DestroyService < Repositories::BaseService
# never be triggered on a read-only instance.
#
# 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
else
container.run_after_commit do
......
......@@ -23,7 +23,7 @@ module Users
private
def record_activity
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
today = Date.today
......
......@@ -124,7 +124,7 @@ module GitGarbageCollectMethods
def update_repository_statistics(resource)
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)
end
......
......@@ -11,7 +11,7 @@ class PagesDomainVerificationCronWorker # rubocop:disable Scalability/Idempotent
worker_resource_boundary :cpu
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|
with_context(project: domain.project) do
......
......@@ -12,7 +12,7 @@ class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWork
# rubocop: disable CodeReuse/ActiveRecord
def perform(domain_id)
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
domain = PagesDomain.find_by(id: domain_id)
......
......@@ -44,7 +44,7 @@ class ProjectCacheWorker
# statistics to become accurate if they were already updated once in the
# last 15 minutes.
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)
Projects::UpdateStatisticsService.new(project, nil, statistics: statistics).execute
......
......@@ -23,7 +23,7 @@ module Projects
end
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!
rescue StandardError => err
......
......@@ -12,7 +12,7 @@ class ScheduleMergeRequestCleanupRefsWorker
idempotent!
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)
MergeRequestCleanupRefsWorker.perform_with_capacity
......
......@@ -4,6 +4,6 @@
# `Shard.connected?` could be cached and return true even though the table doesn't exist
return unless Shard.connected?
return unless ActiveRecord::Migrator.current_version >= 20190402150158
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
Shard.populate!
......@@ -445,7 +445,7 @@ module EE
override :perform
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)
table_name = next_table(table_name) if deleted_rows.zero?
......
......@@ -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)
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.
When some write actions are not allowed because the node is a
**secondary**, consider adding the `Gitlab::Database.main.read_only?` or
`Gitlab::Database.main.read_write?` guard, instead of `Gitlab::Geo.secondary?`.
**secondary**, consider adding the `Gitlab::Database.read_only?` or
`Gitlab::Database.read_write?` guard, instead of `Gitlab::Geo.secondary?`.
The database itself will already be read-only in a replicated setup,
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
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=)
- [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.
- [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.
......
......@@ -30,7 +30,7 @@ end
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
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.
We have a Rails Middleware that filters any potentially writing
......
......@@ -54,7 +54,7 @@ module Groups
if params[:state].present?
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
Epic.state_ids.key(preference.roadmap_epics_state)
......
......@@ -131,7 +131,7 @@ module EE
end
def show_ultimate_trial_suitable_env?
::Gitlab.com? && !::Gitlab::Database.main.read_only?
::Gitlab.com? && !::Gitlab::Database.read_only?
end
def token_expiration_enforced?
......
......@@ -454,7 +454,7 @@ module EE
def generate_subscription
return unless persisted?
return if ::Gitlab::Database.main.read_only?
return if ::Gitlab::Database.read_only?
create_gitlab_subscription(
plan_code: Plan::FREE,
......
......@@ -19,7 +19,7 @@ class NamespaceStatistics < ApplicationRecord
COLUMNS_TO_REFRESH = [:wiki_size].freeze
def refresh!(only: [])
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
return unless group?
COLUMNS_TO_REFRESH.each do |column|
......
......@@ -133,7 +133,7 @@ module EE
# @return [AuditEvent, nil] if record is persisted or nil if audit events
# features are not enabled
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!
......
......@@ -15,7 +15,7 @@ module Geo
end
def execute
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
try_obtain_lease do
log_info('Prune Geo Event Log entries up to id', geo_event_log_id: event_log_min_id)
......
......@@ -46,7 +46,7 @@ module EE
end
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
......@@ -16,7 +16,7 @@ module Geo
tags :exclude_from_gitlab_com
def perform
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
return unless Gitlab::Database.main.healthy?
unless ::GeoNode.secondary_nodes.any?
......
......@@ -18,7 +18,7 @@ class ProjectImportScheduleWorker
tags :needs_own_queue
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)
raise ImportStateNotFound unless project&.import_state
......
......@@ -14,7 +14,7 @@ class UpdateAllMirrorsWorker # rubocop:disable Scalability/IdempotentWorker
RESCHEDULE_WAIT = 1.second
def perform
return if Gitlab::Database.main.read_only?
return if Gitlab::Database.read_only?
scheduled = 0
with_lease do
......
......@@ -12,7 +12,7 @@ class UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker # rubocop:disable Scalab
# rubocop: disable CodeReuse/ActiveRecord
def perform
return if ::Gitlab::Database.main.read_only?
return if ::Gitlab::Database.read_only?
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|
......
......@@ -10,7 +10,7 @@ module EE
override :update_user
def update_user
return if ::Gitlab::Database.main.read_only?
return if ::Gitlab::Database.read_only?
update_user_attributes
update_memberships
......
......@@ -61,7 +61,7 @@ module EE
override :perform
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)
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
module Database
module Connection
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
override :read_only?
def read_only?
::Gitlab::Geo.secondary? || ::Gitlab.maintenance_mode?
end
def healthy?
!Postgresql::ReplicationSlot.lag_too_great?
......
......@@ -25,7 +25,7 @@ module EE
end
def geo_custom_action?
return unless ::Gitlab::Database.main.read_only?
return unless ::Gitlab::Database.read_only?
return unless ::Gitlab::Geo.secondary_with_primary?
receive_pack? || upload_pack_and_not_replicated?
......@@ -55,7 +55,7 @@ module EE
end
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"
end
......
......@@ -10,7 +10,7 @@ RSpec.describe ApplicationHelper do
context 'when not in a Geo secondary' 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')
end
......@@ -38,7 +38,7 @@ RSpec.describe ApplicationHelper do
context 'when database is read-only' 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(/#{default_maintenance_mode_message}/)
......
......@@ -49,7 +49,7 @@ RSpec.describe Gitlab::BackgroundMigration::PruneOrphanedGeoEvents, geo: false,
end
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 }
end
......
......@@ -7,47 +7,6 @@ RSpec.describe Gitlab::Database::Connection do
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
it 'returns true when replication lag is not too great' do
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
context 'on a read-only instance' 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
it 'does not block user in GitLab' do
......@@ -76,7 +76,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
context 'on a read-only instance' 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
it 'does not unblock user in GitLab' do
......@@ -102,7 +102,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
context 'on a read-only instance' 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
it 'does not block user in GitLab' do
......@@ -145,7 +145,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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)
end
......@@ -181,7 +181,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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)
end
......@@ -202,7 +202,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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)
end
......@@ -240,7 +240,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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: 'Group2', provider: provider)
......@@ -313,7 +313,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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)
expect { access.update_user }.not_to change(user.keys, :count)
......@@ -377,7 +377,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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')
expect { access.update_user }.not_to change(user.identities.where(provider: :kerberos), :count)
......@@ -398,7 +398,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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
......
......@@ -32,7 +32,7 @@ RSpec.describe Gitlab::GitAccess do
context "when in a read-only GitLab instance" do
before do
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
let(:primary_repo_url) { geo_primary_http_url_to_repo(project) }
......
......@@ -40,7 +40,7 @@ RSpec.describe Gitlab::GitAccessWiki do
context 'when in a read-only GitLab instance' do
before do
allow(Gitlab::Database.main).to receive(:read_only?) { true }
allow(Gitlab::Database).to receive(:read_only?) { true }
end
it 'does not give access to upload wiki code' do
......@@ -153,7 +153,7 @@ RSpec.describe Gitlab::GitAccessWiki do
before do
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
let(:primary_repo_url) { geo_primary_http_url_to_repo(project.wiki) }
......
......@@ -840,7 +840,7 @@ RSpec.describe Group do
context 'in read-only mode' 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)
end
......
......@@ -121,7 +121,7 @@ RSpec.describe Namespace do
context 'when DB is read-only' do
before do
expect(Gitlab::Database.main).to receive(:read_only?) { true }
expect(Gitlab::Database).to receive(:read_only?) { true }
end
it 'returns free plan' do
......
......@@ -287,7 +287,7 @@ RSpec.describe User do
end
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)
end
......@@ -303,7 +303,7 @@ RSpec.describe User do
end
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)
end
......
......@@ -26,7 +26,7 @@ RSpec.describe NamespaceStatistics do
context 'when database is read_only' 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!)
......
......@@ -92,7 +92,7 @@ RSpec.describe AuditEventService, :request_store do
context 'on a read-only instance' 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
it 'does not create an event' do
......@@ -336,7 +336,7 @@ RSpec.describe AuditEventService, :request_store do
context 'on a read-only instance' 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
it 'does not create an event record in the database' do
......
......@@ -7,7 +7,7 @@ RSpec.describe Keys::LastUsedService do
key = create(:key, last_used_at: 1.year.ago)
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
expect(key.reload.last_used_at).to be_like_time(original_time)
......
......@@ -33,7 +33,7 @@ RSpec.describe PostReceive do
context 'when DB is readonly' do
before do
allow(Gitlab::Database.main).to receive(:read_only?) { true }
allow(Gitlab::Database).to receive(:read_only?) { true }
end
it 'does not call RepositoryPushAuditEventWorker' do
......@@ -45,7 +45,7 @@ RSpec.describe PostReceive do
context 'when DB is not readonly' do
before do
allow(Gitlab::Database.main).to receive(:read_only?) { false }
allow(Gitlab::Database).to receive(:read_only?) { false }
end
it 'calls RepositoryPushAuditEventWorker' do
......
......@@ -17,7 +17,7 @@ RSpec.describe ProjectImportScheduleWorker do
end
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)
subject
......
......@@ -18,7 +18,7 @@ RSpec.describe UpdateAllMirrorsWorker do
describe '#perform' 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!)
worker.perform
......
......@@ -14,7 +14,7 @@ RSpec.describe UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker do
let(:subscription_attrs) { nil }
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 }
end
......
......@@ -42,7 +42,7 @@ module API
def update_project_feature_usage_for(project)
# Prevent errors on GitLab Geo not allowing
# 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?)
end
......
......@@ -394,7 +394,7 @@ module Gitlab
end
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
user.increment_failed_attempts!
......
......@@ -21,7 +21,7 @@ module Gitlab
# Whether user is allowed, or not, we should update
# permissions to keep things clean
if access.allowed?
unless Gitlab::Database.main.read_only?
unless Gitlab::Database.read_only?
access.update_user
Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute
end
......
......@@ -173,6 +173,14 @@ module Gitlab
ActiveRecord::Base.prepend(ActiveRecordBaseTransactionMetrics)
end
def self.read_only?
false
end
def self.read_write?
!read_only?
end
# MonkeyPatch for ActiveRecord::Base for adding observability
module ActiveRecordBaseTransactionMetrics
extend ActiveSupport::Concern
......@@ -189,3 +197,5 @@ module Gitlab
end
end
end
Gitlab::Database.prepend_mod_with('Gitlab::Database')
......@@ -80,14 +80,6 @@ module Gitlab
scope.establish_connection(config.merge(prepared_statements: false))
end
def read_only?
false
end
def read_write?
!read_only?
end
# Check whether the underlying database is in read-only mode
def db_read_only?
pg_is_in_recovery =
......
......@@ -257,7 +257,7 @@ module Gitlab
def check_db_accessibility!
return unless receive_pack?
if Gitlab::Database.main.read_only?
if Gitlab::Database.read_only?
raise ForbiddenError, push_to_read_only_message
end
end
......
......@@ -71,7 +71,7 @@ module Gitlab
def create_cached_signature!
using_keychain do |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)
end
......
......@@ -71,7 +71,7 @@ module Gitlab
end
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.with_lock do
......
......@@ -38,7 +38,7 @@ module Gitlab
end
def save_markdown(updates)
return unless persisted? && Gitlab::Database.main.read_write?
return unless persisted? && Gitlab::Database.read_write?
update_columns(updates)
end
......
......@@ -59,7 +59,7 @@ module Gitlab
# Overridden in EE module
def read_only?
Gitlab::Database.main.read_only?
Gitlab::Database.read_only?
end
def json_request?
......
......@@ -49,7 +49,7 @@ module Gitlab
def create_cached_signature!
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)
end
......
......@@ -4,7 +4,7 @@ namespace :gitlab do
namespace :storage do
desc 'GitLab | Storage | Migrate existing projects to Hashed Storage'
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.'
end
......@@ -50,7 +50,7 @@ namespace :gitlab do
desc 'GitLab | Storage | Rollback existing projects to Legacy Storage'
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.'
end
......
......@@ -179,7 +179,7 @@ RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do
context 'on a read-only instance' 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
it 'does not attempt to write to the database with valid otp' do
......
......@@ -24,7 +24,7 @@ RSpec.describe Repositories::GitHttpController do
context 'on a read-only instance' 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
it 'does not update project statistics' do
......
......@@ -37,7 +37,7 @@ RSpec.describe 'Admin Mode Logout', :js do
context 'on a read-only instance' 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
it 'disable removes admin mode and redirects to root page' do
......
......@@ -57,7 +57,7 @@ RSpec.describe 'Admin mode', :js do
context 'on a read-only instance' 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
it 'can enter admin mode' do
......@@ -117,7 +117,7 @@ RSpec.describe 'Admin mode', :js do
context 'on a read-only instance' 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
it 'can leave admin mode' do
......
......@@ -315,7 +315,7 @@ RSpec.describe 'Branches' do
context 'on a read-only instance' 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
it_behaves_like 'compares branches'
......
......@@ -40,7 +40,7 @@ RSpec.describe "Compare", :js do
context 'on a read-only instance' 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
it_behaves_like 'compares branches'
......
......@@ -11,7 +11,7 @@ RSpec.describe 'read-only message' do
context 'when database is read-only' 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
it_behaves_like 'Read-only instance', /You are on a read\-only GitLab instance./
......@@ -19,7 +19,7 @@ RSpec.describe 'read-only message' do
context 'when database is in read-write mode' 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
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
context 'on a read-only instance' 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
it 'sign out redirects to sign in page' do
......
......@@ -65,7 +65,7 @@ RSpec.describe Banzai::Renderer do
end
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!)
is_expected.to eq('field_html')
......
......@@ -22,7 +22,7 @@ RSpec.describe Gitlab::Auth::Ldap::Access do
end
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) }
.not_to change { user.last_credential_check_at }
......
......@@ -844,7 +844,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
context 'when the database is read-only' 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
it 'does not increment failed_attempts when true and password is incorrect' do
......
......@@ -162,18 +162,6 @@ RSpec.describe Gitlab::Database::Connection do
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
it 'detects a read-only database' do
allow(connection.scope.connection)
......
......@@ -190,6 +190,18 @@ RSpec.describe Gitlab::Database do
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
def subscribe_events
events = []
......
......@@ -392,7 +392,7 @@ RSpec.describe Gitlab::GitAccess do
context 'when in a read-only GitLab instance' do
before do
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
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
let(:message) { "You can't push code to a read-only GitLab instance." }
before do
allow(Gitlab::Database.main).to receive(:read_only?) { true }
allow(Gitlab::Database).to receive(:read_only?) { true }
end
it_behaves_like 'forbidden git access'
......
......@@ -91,7 +91,7 @@ RSpec.describe Gitlab::Gpg::Commit do
context 'read-only mode' 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
it 'does not create a cached signature' do
......
......@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Middleware::ReadOnly do
context 'when database is read-only' do
before do
allow(Gitlab::Database.main).to receive(:read_only?) { true }
allow(Gitlab::Database).to receive(:read_only?) { true }
end
it_behaves_like 'write access for a read-only GitLab instance'
......
......@@ -99,7 +99,7 @@ RSpec.describe DeprecatedAssignee do
context 'when DB is read-only' do
before do
allow(Gitlab::Database.main).to receive(:read_only?) { true }
allow(Gitlab::Database).to receive(:read_only?) { true }
end
it 'returns a users relation' do
......@@ -139,7 +139,7 @@ RSpec.describe DeprecatedAssignee do
context 'when DB is read-only' do
before do
allow(Gitlab::Database.main).to receive(:read_only?) { true }
allow(Gitlab::Database).to receive(:read_only?) { true }
end
it 'returns a list of user IDs' do
......
......@@ -214,7 +214,7 @@ RSpec.describe ProjectStatistics do
context 'when the database is read-only' 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_repository_size)
......
......@@ -86,7 +86,7 @@ RSpec.describe SnippetStatistics do
context 'when the database is read-only' 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_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