Commit d838c0b2 authored by John Cai's avatar John Cai Committed by Stan Hu

Fix existing migrations for repository_storages_weighted column

For instances that upgraded to GitLab 13.1.x, it's likely that the
`application_settings.repository_storages_weighted` column did not
properly update. This happened because the schema for
`ApplicationSetting` may have been cached, so the newly-added column
wasn't visible to the model.

To ensure the column always has the right data, we make the
pre-deployment migration fill in the right data and flush the
cache. This essentially does the same thing as the post-deployment
migration, but it ensures that the application can properly run before
post-deployment migrations have completed.

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/225588
parent e982a73d
---
title: Fix existing repository_storages_weighted migrations
merge_request: 35814
author:
type: fixed
...@@ -3,11 +3,37 @@ ...@@ -3,11 +3,37 @@
class AddRepositoryStoragesWeightedToApplicationSettings < ActiveRecord::Migration[6.0] class AddRepositoryStoragesWeightedToApplicationSettings < ActiveRecord::Migration[6.0]
DOWNTIME = false DOWNTIME = false
class ApplicationSetting < ActiveRecord::Base
serialize :repository_storages
self.table_name = 'application_settings'
end
def up def up
add_column :application_settings, :repository_storages_weighted, :jsonb, default: {}, null: false add_column :application_settings, :repository_storages_weighted, :jsonb, default: {}, null: false
seed_repository_storages_weighted
end end
def down def down
remove_column :application_settings, :repository_storages_weighted remove_column :application_settings, :repository_storages_weighted
end end
private
def seed_repository_storages_weighted
# We need to flush the cache to ensure the newly-added column is loaded
ApplicationSetting.reset_column_information
# There should only be one row here due to
# 20200420162730_remove_additional_application_settings_rows.rb
ApplicationSetting.all.each do |settings|
storages = Gitlab.config.repositories.storages.keys.collect do |storage|
weight = settings.repository_storages.include?(storage) ? 100 : 0
[storage.to_sym, weight]
end
settings.repository_storages_weighted = Hash[storages]
settings.save!
end
end
end end
# frozen_string_literal: true # frozen_string_literal: true
class SeedRepositoryStoragesWeighted < ActiveRecord::Migration[6.0] class SeedRepositoryStoragesWeighted < ActiveRecord::Migration[6.0]
DOWNTIME = false
class ApplicationSetting < ActiveRecord::Base class ApplicationSetting < ActiveRecord::Base
serialize :repository_storages serialize :repository_storages
self.table_name = 'application_settings' self.table_name = 'application_settings'
end end
def up def up
# We need to flush the cache to ensure the newly-added column is loaded
ApplicationSetting.reset_column_information
# There should only be one row here due to
# 20200420162730_remove_additional_application_settings_rows.rb
ApplicationSetting.all.each do |settings| ApplicationSetting.all.each do |settings|
storages = Gitlab.config.repositories.storages.keys.collect do |storage| storages = Gitlab.config.repositories.storages.keys.collect do |storage|
weight = settings.repository_storages.include?(storage) ? 100 : 0 weight = settings.repository_storages.include?(storage) ? 100 : 0
[storage, weight] [storage.to_sym, weight]
end end
settings.repository_storages_weighted = Hash[storages] settings.repository_storages_weighted = Hash[storages]
......
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'migrate', '20200508203901_add_repository_storages_weighted_to_application_settings.rb')
RSpec.describe AddRepositoryStoragesWeightedToApplicationSettings, :migration do
let(:storages) { { "foo" => {}, "baz" => {} } }
let(:application_settings) do
table(:application_settings).tap do |klass|
klass.class_eval do
serialize :repository_storages
end
end
end
before do
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
end
let(:application_setting) { application_settings.create! }
let(:repository_storages) { ["foo"] }
it 'populates repository_storages_weighted properly' do
application_setting.repository_storages = repository_storages
application_setting.save!
migrate!
expect(application_settings.find(application_setting.id).repository_storages_weighted).to eq({ "foo" => 100, "baz" => 0 })
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