Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2018-11-22 19:17:08 +0300
committerNick Thomas <nick@gitlab.com>2018-11-27 21:24:18 +0300
commit6ddefe7cada5268469561c70a8557cf1545684b2 (patch)
tree3f54240e3472da4c4f6004ae19da20f78ba476f3 /lib
parent0afce35d65aa433d221e41632c6d8095ab68c39f (diff)
Correctly handle data-loss scenarios when encrypting columns
If the EncryptColumns background migration runs in a sidekiq with a stale view of the database schema, or when the purported destination columns don't actually exist, data loss can result. Attempt to work around these issues by reloading schema information before running the migration, and raising errors if the model reports that any of its source or destination columns are missing.
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/background_migration/encrypt_columns.rb14
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/gitlab/background_migration/encrypt_columns.rb b/lib/gitlab/background_migration/encrypt_columns.rb
index 0d333e47e7b..bd5f12276ab 100644
--- a/lib/gitlab/background_migration/encrypt_columns.rb
+++ b/lib/gitlab/background_migration/encrypt_columns.rb
@@ -17,6 +17,12 @@ module Gitlab
class EncryptColumns
def perform(model, attributes, from, to)
model = model.constantize if model.is_a?(String)
+
+ # If sidekiq hasn't undergone a restart, its idea of what columns are
+ # present may be inaccurate, so ensure this is as fresh as possible
+ model.reset_column_information
+ model.define_attribute_methods
+
attributes = expand_attributes(model, Array(attributes).map(&:to_sym))
model.transaction do
@@ -41,6 +47,14 @@ module Gitlab
raise "Couldn't determine encrypted column for #{klass}##{attribute}" if
crypt_column_name.nil?
+ raise "#{klass} source column: #{attribute} is missing" unless
+ klass.column_names.include?(attribute.to_s)
+
+ # Running the migration without the destination column being present
+ # leads to data loss
+ raise "#{klass} destination column: #{crypt_column_name} is missing" unless
+ klass.column_names.include?(crypt_column_name.to_s)
+
[attribute, crypt_column_name]
end