Geo migrations settings are included by default

Changelog: changed
EE: true
parent 61d93f77
...@@ -69,18 +69,19 @@ module Gitlab ...@@ -69,18 +69,19 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/handle_malformed_strings') require_dependency Rails.root.join('lib/gitlab/middleware/handle_malformed_strings')
require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory') require_dependency Rails.root.join('lib/gitlab/middleware/rack_multipart_tempfile_factory')
require_dependency Rails.root.join('lib/gitlab/runtime') require_dependency Rails.root.join('lib/gitlab/runtime')
require_dependency Rails.root.join('lib/gitlab/patch/legacy_database_config') require_dependency Rails.root.join('lib/gitlab/patch/database_config')
require_dependency Rails.root.join('lib/gitlab/exceptions_app') require_dependency Rails.root.join('lib/gitlab/exceptions_app')
config.exceptions_app = Gitlab::ExceptionsApp.new(Rails.public_path) config.exceptions_app = Gitlab::ExceptionsApp.new(Rails.public_path)
# To be removed in 15.0 # This preload is required to:
# This preload is needed to convert legacy `database.yml` #
# from `production: adapter: postgresql` # 1. Convert legacy `database.yml`;
# into a `production: main: adapter: postgresql` # 2. Include Geo post-deployment migrations settings;
unless Gitlab::Utils.to_boolean(ENV['SKIP_DATABASE_CONFIG_VALIDATION'], default: false) #
config.class.prepend(::Gitlab::Patch::LegacyDatabaseConfig) # TODO: In 15.0, this preload can be wrapped in a Gitlab.ee block
end # since we don't need to convert legacy `database.yml` anymore.
config.class.prepend(::Gitlab::Patch::DatabaseConfig)
# Settings in config/environments/* take precedence over those specified here. # Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers # Application configuration should go into files in config/initializers
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do RSpec.describe Gitlab::Patch::DatabaseConfig do
describe '#load_geo_database_yaml' do describe '#load_geo_database_yaml' do
let(:configuration) { Rails::Application::Configuration.new(Rails.root) } let(:configuration) { Rails::Application::Configuration.new(Rails.root) }
...@@ -35,7 +35,7 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do ...@@ -35,7 +35,7 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do
allow(Pathname) allow(Pathname)
.to receive(:new).with(Rails.root.join('config/database_geo.yml')) .to receive(:new).with(Rails.root.join('config/database_geo.yml'))
.and_return(double(read: database_geo_yml)) .and_return(instance_double('Pathname', read: database_geo_yml))
end end
context 'when config/database_geo.yml use a new syntax' do context 'when config/database_geo.yml use a new syntax' do
...@@ -129,62 +129,158 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do ...@@ -129,62 +129,158 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do
# rubocop:enable RSpec/AnyInstanceOf # rubocop:enable RSpec/AnyInstanceOf
end end
context 'when config/database_geo.yml does not exist' do shared_examples 'hash containing main: connection name' do
shared_examples 'hash containing main: connection name' do it 'returns a hash containing only main:' do
it 'returns a hash containing only main:' do database_configuration = configuration.database_configuration
expect(database_configuration).to match(
"production" => { "main" => a_hash_including("adapter") },
"development" => { "main" => a_hash_including("adapter" => "postgresql") },
"test" => { "main" => a_hash_including("adapter" => "postgresql") }
)
end
end
shared_examples 'hash containing both main: and geo: connection names' do
it 'returns a hash containing both main: and geo:' do
database_configuration = configuration.database_configuration
expect(database_configuration).to match(
"production" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter", "migrations_paths" => ["ee/db/geo/migrate", "ee/db/geo/post_migrate"], "schema_migrations_path" => "ee/db/geo/schema_migrations") },
"development" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter" => "postgresql", "migrations_paths" => ["ee/db/geo/migrate", "ee/db/geo/post_migrate"], "schema_migrations_path" => "ee/db/geo/schema_migrations") },
"test" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter" => "postgresql", "migrations_paths" => ["ee/db/geo/migrate", "ee/db/geo/post_migrate"], "schema_migrations_path" => "ee/db/geo/schema_migrations") }
)
end
context 'when SKIP_POST_DEPLOYMENT_MIGRATIONS environment variable set' do
before do
stub_env('SKIP_POST_DEPLOYMENT_MIGRATIONS', 'true')
end
it 'does not include Geo post deployment migrations path' do
database_configuration = configuration.database_configuration database_configuration = configuration.database_configuration
expect(database_configuration).to match( expect(database_configuration).to match(
"production" => { "main" => a_hash_including("adapter") }, "production" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter", "migrations_paths" => ["ee/db/geo/migrate"], "schema_migrations_path" => "ee/db/geo/schema_migrations") },
"development" => { "main" => a_hash_including("adapter" => "postgresql") }, "development" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter" => "postgresql", "migrations_paths" => ["ee/db/geo/migrate"], "schema_migrations_path" => "ee/db/geo/schema_migrations") },
"test" => { "main" => a_hash_including("adapter" => "postgresql") } "test" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter" => "postgresql", "migrations_paths" => ["ee/db/geo/migrate"], "schema_migrations_path" => "ee/db/geo/schema_migrations") }
) )
end end
end end
end
context 'when config/database_geo.yml does not exist' do
before do before do
allow(File).to receive(:exist?).and_call_original allow(File).to receive(:exist?).and_call_original
allow(File).to receive(:exist?).with(Rails.root.join("config/database_geo.yml")).and_return(false) allow(File).to receive(:exist?).with(Rails.root.join("config/database_geo.yml")).and_return(false)
end end
context 'when config/database.yml use a new syntax' do context 'when config/database.yml use a new syntax' do
let(:database_yml) do context 'and does not contain Geo settings' do
<<-EOS let(:database_yml) do
production: <<-EOS
main: production:
adapter: postgresql main:
encoding: unicode adapter: postgresql
database: gitlabhq_production encoding: unicode
username: git database: gitlabhq_production
password: "secure password" username: git
host: localhost password: "secure password"
host: localhost
development:
main: development:
adapter: postgresql main:
encoding: unicode adapter: postgresql
database: gitlabhq_development encoding: unicode
username: postgres database: gitlabhq_development
password: "secure password" username: postgres
host: localhost password: "secure password"
variables: host: localhost
statement_timeout: 15s variables:
statement_timeout: 15s
test: &test
main: test: &test
adapter: postgresql main:
encoding: unicode adapter: postgresql
database: gitlabhq_test encoding: unicode
username: postgres database: gitlabhq_test
password: username: postgres
host: localhost password:
prepared_statements: false host: localhost
variables: prepared_statements: false
statement_timeout: 15s variables:
EOS statement_timeout: 15s
EOS
end
include_examples 'hash containing main: connection name'
end end
include_examples 'hash containing main: connection name' context 'contains Geo settings' do
let(:database_yml) do
<<-EOS
production:
main:
adapter: postgresql
encoding: unicode
database: gitlabhq_production
username: git
password: "secure password"
host: localhost
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_production
username: git
password: "secure password"
host: localhost
development:
main:
adapter: postgresql
encoding: unicode
database: gitlabhq_development
username: postgres
password: "secure password"
host: localhost
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_development
username: postgres
password: "secure password"
host: localhost
variables:
statement_timeout: 15s
test: &test
main:
adapter: postgresql
encoding: unicode
database: gitlabhq_test
username: postgres
password:
host: localhost
prepared_statements: false
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_test
username: postgres
password:
host: localhost
prepared_statements: false
variables:
statement_timeout: 15s
EOS
end
include_examples 'hash containing both main: and geo: connection names'
end
end end
context 'when config/database.yml use a legacy syntax' do context 'when config/database.yml use a legacy syntax' do
...@@ -268,18 +364,6 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do ...@@ -268,18 +364,6 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do
EOS EOS
end end
shared_examples 'hash containing both main: and geo: connection names' do
it 'returns a hash containing both main: and geo:' do
database_configuration = configuration.database_configuration
expect(database_configuration).to match(
"production" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter") },
"development" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter" => "postgresql") },
"test" => { "main" => a_hash_including("adapter"), "geo" => a_hash_including("adapter" => "postgresql") }
)
end
end
before do before do
# The `AS::ConfigurationFile` calls `read` in `def initialize` # The `AS::ConfigurationFile` calls `read` in `def initialize`
# thus we cannot use `allow_next_instance_of` # thus we cannot use `allow_next_instance_of`
...@@ -290,43 +374,111 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do ...@@ -290,43 +374,111 @@ RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do
end end
context 'when config/database.yml use a new syntax' do context 'when config/database.yml use a new syntax' do
let(:database_yml) do context 'and does not contain Geo setting' do
<<-EOS let(:database_yml) do
production: <<-EOS
main: production:
adapter: postgresql main:
encoding: unicode adapter: postgresql
database: gitlabhq_production encoding: unicode
username: git database: gitlabhq_production
password: "secure password" username: git
host: localhost password: "secure password"
host: localhost
development:
main: development:
adapter: postgresql main:
encoding: unicode adapter: postgresql
database: gitlabhq_development encoding: unicode
username: postgres database: gitlabhq_development
password: "secure password" username: postgres
host: localhost password: "secure password"
variables: host: localhost
statement_timeout: 15s variables:
statement_timeout: 15s
test: &test
main: test: &test
adapter: postgresql main:
encoding: unicode adapter: postgresql
database: gitlabhq_test encoding: unicode
username: postgres database: gitlabhq_test
password: username: postgres
host: localhost password:
prepared_statements: false host: localhost
variables: prepared_statements: false
statement_timeout: 15s variables:
EOS statement_timeout: 15s
EOS
end
include_examples 'hash containing both main: and geo: connection names'
end end
include_examples 'hash containing both main: and geo: connection names' context 'contains Geo setting' do
let(:database_yml) do
<<-EOS
production:
main:
adapter: postgresql
encoding: unicode
database: gitlabhq_production
username: git
password: "secure password"
host: localhost
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_production
username: git
password: "secure password"
host: localhost
development:
main:
adapter: postgresql
encoding: unicode
database: gitlabhq_development
username: postgres
password: "secure password"
host: localhost
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_development
username: postgres
password: "secure password"
host: localhost
variables:
statement_timeout: 15s
test: &test
main:
adapter: postgresql
encoding: unicode
database: gitlabhq_test
username: postgres
password:
host: localhost
prepared_statements: false
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_test
username: postgres
password:
host: localhost
prepared_statements: false
variables:
statement_timeout: 15s
EOS
end
include_examples 'hash containing both main: and geo: connection names'
end
end end
context 'when config/database.yml use a legacy syntax' do context 'when config/database.yml use a legacy syntax' do
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
module Gitlab module Gitlab
module Patch module Patch
module LegacyDatabaseConfig module DatabaseConfig
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
...@@ -73,23 +73,34 @@ module Gitlab ...@@ -73,23 +73,34 @@ module Gitlab
@uses_legacy_database_config = false # rubocop:disable Gitlab/ModuleWithInstanceVariables @uses_legacy_database_config = false # rubocop:disable Gitlab/ModuleWithInstanceVariables
super.to_h do |env, configs| super.to_h do |env, configs|
# This check is taken from Rails where the transformation # TODO: To be removed in 15.0. See https://gitlab.com/gitlab-org/gitlab/-/issues/338182
# of a flat database.yml is done into `primary:` # This preload is needed to convert legacy `database.yml`
# https://github.com/rails/rails/blob/v6.1.4/activerecord/lib/active_record/database_configurations.rb#L169 # from `production: adapter: postgresql`
if configs.is_a?(Hash) && !configs.all? { |_, v| v.is_a?(Hash) } # into a `production: main: adapter: postgresql`
configs = { "main" => configs } unless Gitlab::Utils.to_boolean(ENV['SKIP_DATABASE_CONFIG_VALIDATION'], default: false)
# This check is taken from Rails where the transformation
@uses_legacy_database_config = true # rubocop:disable Gitlab/ModuleWithInstanceVariables # of a flat database.yml is done into `primary:`
# https://github.com/rails/rails/blob/v6.1.4/activerecord/lib/active_record/database_configurations.rb#L169
if configs.is_a?(Hash) && !configs.all? { |_, v| v.is_a?(Hash) }
configs = { "main" => configs }
@uses_legacy_database_config = true # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
end end
if Gitlab.ee? && File.exist?(Rails.root.join("config/database_geo.yml")) if Gitlab.ee?
migrations_paths = ["ee/db/geo/migrate"] if !configs.key?("geo") && File.exist?(Rails.root.join("config/database_geo.yml"))
migrations_paths << "ee/db/geo/post_migrate" unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS'] configs["geo"] = Rails.application.config_for(:database_geo).stringify_keys
end
if configs.key?("geo")
migrations_paths = Array(configs["geo"]["migrations_paths"])
migrations_paths << "ee/db/geo/migrate" if migrations_paths.empty?
migrations_paths << "ee/db/geo/post_migrate" unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
configs["geo"] = configs["geo"]["migrations_paths"] = migrations_paths.uniq
Rails.application.config_for(:database_geo) configs["geo"]["schema_migrations_path"] = "ee/db/geo/schema_migrations" if configs["geo"]["schema_migrations_path"].blank?
.merge(migrations_paths: migrations_paths, schema_migrations_path: "ee/db/geo/schema_migrations") end
.stringify_keys
end end
[env, configs] [env, configs]
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::Patch::LegacyDatabaseConfig do RSpec.describe Gitlab::Patch::DatabaseConfig do
it 'module is included' do it 'module is included' do
expect(Rails::Application::Configuration).to include(described_class) expect(Rails::Application::Configuration).to include(described_class)
end end
......
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