gitlab-org--gitlab-foss/lib/gitlab/downtime_check.rb
Yorick Peterse a8bfe20d0d
Added checks for migration downtime
These new checks can be used to check if migrations require downtime or
not (as tagged by their authors). In CI this compares the current branch
with master so migrations added by merge requests are automatically
verified.

To check the migrations added since a Git reference simply run:

    bundle exec rake gitlab:db:downtime_check[GIT_REF]
2016-07-20 12:41:56 +02:00

71 lines
2.1 KiB
Ruby

module Gitlab
# Checks if a set of migrations requires downtime or not.
class DowntimeCheck
# The constant containing the boolean that indicates if downtime is needed
# or not.
DOWNTIME_CONST = :DOWNTIME
# The constant that specifies the reason for the migration requiring
# downtime.
DOWNTIME_REASON_CONST = :DOWNTIME_REASON
# Checks the given migration paths and returns an Array of
# `Gitlab::DowntimeCheck::Message` instances.
#
# migrations - The migration file paths to check.
def check(migrations)
migrations.map do |path|
require(path)
migration_class = class_for_migration_file(path)
unless migration_class.const_defined?(DOWNTIME_CONST)
raise "The migration in #{path} does not specify if it requires " \
"downtime or not"
end
if online?(migration_class)
Message.new(path)
else
reason = downtime_reason(migration_class)
unless reason
raise "The migration in #{path} requires downtime but no reason " \
"was given"
end
Message.new(path, true, reason)
end
end
end
# Checks the given migrations and prints the results to STDOUT/STDERR.
#
# migrations - The migration file paths to check.
def check_and_print(migrations)
check(migrations).each do |message|
puts message.to_s # rubocop: disable Rails/Output
end
end
# Returns the class for the given migration file path.
def class_for_migration_file(path)
File.basename(path, File.extname(path)).split('_', 2).last.camelize.
constantize
end
# Returns true if the given migration can be performed without downtime.
def online?(migration)
migration.const_get(DOWNTIME_CONST) == false
end
# Returns the downtime reason, or nil if none was defined.
def downtime_reason(migration)
if migration.const_defined?(DOWNTIME_REASON_CONST)
migration.const_get(DOWNTIME_REASON_CONST)
else
nil
end
end
end
end