diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 20:02:30 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 20:02:30 +0000 |
commit | 41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch) | |
tree | 9c8d89a8624828992f06d892cd2f43818ff5dcc8 /lib/backup | |
parent | 0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff) | |
download | gitlab-ce-41fe97390ceddf945f3d967b8fdb3de4c66b7dea.tar.gz |
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
Diffstat (limited to 'lib/backup')
-rw-r--r-- | lib/backup/artifacts.rb | 7 | ||||
-rw-r--r-- | lib/backup/builds.rb | 7 | ||||
-rw-r--r-- | lib/backup/database.rb | 77 | ||||
-rw-r--r-- | lib/backup/files.rb | 27 | ||||
-rw-r--r-- | lib/backup/gitaly_backup.rb | 18 | ||||
-rw-r--r-- | lib/backup/gitaly_rpc_backup.rb | 9 | ||||
-rw-r--r-- | lib/backup/lfs.rb | 7 | ||||
-rw-r--r-- | lib/backup/manager.rb | 257 | ||||
-rw-r--r-- | lib/backup/packages.rb | 7 | ||||
-rw-r--r-- | lib/backup/pages.rb | 7 | ||||
-rw-r--r-- | lib/backup/registry.rb | 8 | ||||
-rw-r--r-- | lib/backup/repositories.rb | 24 | ||||
-rw-r--r-- | lib/backup/task.rb | 46 | ||||
-rw-r--r-- | lib/backup/terraform_state.rb | 7 | ||||
-rw-r--r-- | lib/backup/uploads.rb | 7 |
15 files changed, 302 insertions, 213 deletions
diff --git a/lib/backup/artifacts.rb b/lib/backup/artifacts.rb index 163446998e9..4ef76b0aaf3 100644 --- a/lib/backup/artifacts.rb +++ b/lib/backup/artifacts.rb @@ -2,14 +2,11 @@ module Backup class Artifacts < Backup::Files - attr_reader :progress - def initialize(progress) - @progress = progress - - super('artifacts', JobArtifactUploader.root, excludes: ['tmp']) + super(progress, 'artifacts', JobArtifactUploader.root, excludes: ['tmp']) end + override :human_name def human_name _('artifacts') end diff --git a/lib/backup/builds.rb b/lib/backup/builds.rb index 51a68ca933d..fbf932e3f6b 100644 --- a/lib/backup/builds.rb +++ b/lib/backup/builds.rb @@ -2,14 +2,11 @@ module Backup class Builds < Backup::Files - attr_reader :progress - def initialize(progress) - @progress = progress - - super('builds', Settings.gitlab_ci.builds_path) + super(progress, 'builds', Settings.gitlab_ci.builds_path) end + override :human_name def human_name _('builds') end diff --git a/lib/backup/database.rb b/lib/backup/database.rb index de26dbab038..afc84a4b913 100644 --- a/lib/backup/database.rb +++ b/lib/backup/database.rb @@ -3,10 +3,10 @@ require 'yaml' module Backup - class Database + class Database < Task + extend ::Gitlab::Utils::Override include Backup::Helper - attr_reader :progress - attr_reader :config, :db_file_name + attr_reader :force, :config IGNORED_ERRORS = [ # Ignore warnings @@ -18,13 +18,14 @@ module Backup ].freeze IGNORED_ERRORS_REGEXP = Regexp.union(IGNORED_ERRORS).freeze - def initialize(progress, filename: nil) - @progress = progress + def initialize(progress, force:) + super(progress) @config = ActiveRecord::Base.configurations.find_db_config(Rails.env).configuration_hash - @db_file_name = filename || File.join(Gitlab.config.backup.path, 'db', 'database.sql.gz') + @force = force end - def dump + override :dump + def dump(db_file_name) FileUtils.mkdir_p(File.dirname(db_file_name)) FileUtils.rm_f(db_file_name) compress_rd, compress_wr = IO.pipe @@ -64,12 +65,24 @@ module Backup raise DatabaseBackupError.new(config, db_file_name) unless success end - def restore + override :restore + def restore(db_file_name) + unless force + progress.puts 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'.color(:yellow) + sleep(5) + end + + # Drop all tables Load the schema to ensure we don't have any newer tables + # hanging out from a failed upgrade + puts_time 'Cleaning the database ... '.color(:blue) + Rake::Task['gitlab:db:drop_tables'].invoke + puts_time 'done'.color(:green) + decompress_rd, decompress_wr = IO.pipe decompress_pid = spawn(*%w(gzip -cd), out: decompress_wr, in: db_file_name) decompress_wr.close - status, errors = + status, @errors = case config[:adapter] when "postgresql" then progress.print "Restoring PostgreSQL database #{database} ... " @@ -81,33 +94,47 @@ module Backup Process.waitpid(decompress_pid) success = $?.success? && status.success? - if errors.present? + if @errors.present? progress.print "------ BEGIN ERRORS -----\n".color(:yellow) - progress.print errors.join.color(:yellow) + progress.print @errors.join.color(:yellow) progress.print "------ END ERRORS -------\n".color(:yellow) end report_success(success) raise Backup::Error, 'Restore failed' unless success + end - if errors.present? - warning = <<~MSG - There were errors in restoring the schema. This may cause - issues if this results in missing indexes, constraints, or - columns. Please record the errors above and contact GitLab - Support if you have questions: - https://about.gitlab.com/support/ - MSG - - warn warning.color(:red) - Gitlab::TaskHelpers.ask_to_continue - end + override :pre_restore_warning + def pre_restore_warning + return if force + + <<-MSG.strip_heredoc + Be sure to stop Puma, Sidekiq, and any other process that + connects to the database before proceeding. For Omnibus + installs, see the following link for more information: + https://docs.gitlab.com/ee/raketasks/backup_restore.html#restore-for-omnibus-gitlab-installations + + Before restoring the database, we will remove all existing + tables to avoid future upgrade problems. Be aware that if you have + custom tables in the GitLab database these tables and all data will be + removed. + MSG end - def enabled - true + override :post_restore_warning + def post_restore_warning + return unless @errors.present? + + <<-MSG.strip_heredoc + There were errors in restoring the schema. This may cause + issues if this results in missing indexes, constraints, or + columns. Please record the errors above and contact GitLab + Support if you have questions: + https://about.gitlab.com/support/ + MSG end + override :human_name def human_name _('database') end diff --git a/lib/backup/files.rb b/lib/backup/files.rb index db6278360a3..7fa07e40cee 100644 --- a/lib/backup/files.rb +++ b/lib/backup/files.rb @@ -1,25 +1,27 @@ # frozen_string_literal: true require 'open3' -require_relative 'helper' module Backup - class Files + class Files < Task + extend ::Gitlab::Utils::Override include Backup::Helper DEFAULT_EXCLUDE = 'lost+found' - attr_reader :name, :backup_tarball, :excludes + attr_reader :name, :excludes + + def initialize(progress, name, app_files_dir, excludes: []) + super(progress) - def initialize(name, app_files_dir, excludes: []) @name = name @app_files_dir = app_files_dir - @backup_tarball = File.join(Gitlab.config.backup.path, name + '.tar.gz') @excludes = [DEFAULT_EXCLUDE].concat(excludes) end # Copy files from public/files to backup/files - def dump + override :dump + def dump(backup_tarball) FileUtils.mkdir_p(Gitlab.config.backup.path) FileUtils.rm_f(backup_tarball) @@ -35,7 +37,7 @@ module Backup unless status == 0 puts output - raise_custom_error + raise_custom_error(backup_tarball) end tar_cmd = [tar, exclude_dirs(:tar), %W[-C #{backup_files_realpath} -cf - .]].flatten @@ -47,11 +49,12 @@ module Backup end unless pipeline_succeeded?(tar_status: status_list[0], gzip_status: status_list[1], output: output) - raise_custom_error + raise_custom_error(backup_tarball) end end - def restore + override :restore + def restore(backup_tarball) backup_existing_files_dir cmd_list = [%w[gzip -cd], %W[#{tar} --unlink-first --recursive-unlink -C #{app_files_realpath} -xf -]] @@ -61,10 +64,6 @@ module Backup end end - def enabled - true - end - def tar if system(*%w[gtar --version], out: '/dev/null') # It looks like we can get GNU tar by running 'gtar' @@ -146,7 +145,7 @@ module Backup end end - def raise_custom_error + def raise_custom_error(backup_tarball) raise FileBackupError.new(app_files_realpath, backup_tarball) end diff --git a/lib/backup/gitaly_backup.rb b/lib/backup/gitaly_backup.rb index 8ac09e94004..b688ff7f13b 100644 --- a/lib/backup/gitaly_backup.rb +++ b/lib/backup/gitaly_backup.rb @@ -9,13 +9,16 @@ module Backup # @param [StringIO] progress IO interface to output progress # @param [Integer] max_parallelism max parallelism when running backups # @param [Integer] storage_parallelism max parallelism per storage (is affected by max_parallelism) - def initialize(progress, max_parallelism: nil, storage_parallelism: nil) + # @param [String] backup_id unique identifier for the backup + def initialize(progress, max_parallelism: nil, storage_parallelism: nil, incremental: false, backup_id: nil) @progress = progress @max_parallelism = max_parallelism @storage_parallelism = storage_parallelism + @incremental = incremental + @backup_id = backup_id end - def start(type) + def start(type, backup_repos_path) raise Error, 'already started' if started? command = case type @@ -30,6 +33,13 @@ module Backup args = [] args += ['-parallel', @max_parallelism.to_s] if @max_parallelism args += ['-parallel-storage', @storage_parallelism.to_s] if @storage_parallelism + if Feature.enabled?(:incremental_repository_backup, default_enabled: :yaml) + args += ['-layout', 'pointer'] + if type == :create + args += ['-incremental'] if @incremental + args += ['-id', @backup_id] if @backup_id + end + end @input_stream, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args) @@ -93,10 +103,6 @@ module Backup @thread.present? end - def backup_repos_path - File.absolute_path(File.join(Gitlab.config.backup.path, 'repositories')) - end - def bin_path File.absolute_path(Gitlab.config.backup.gitaly_backup_path) end diff --git a/lib/backup/gitaly_rpc_backup.rb b/lib/backup/gitaly_rpc_backup.rb index bbd83cd2157..89ed27cfa13 100644 --- a/lib/backup/gitaly_rpc_backup.rb +++ b/lib/backup/gitaly_rpc_backup.rb @@ -7,10 +7,11 @@ module Backup @progress = progress end - def start(type) + def start(type, backup_repos_path) raise Error, 'already started' if @type @type = type + @backup_repos_path = backup_repos_path case type when :create FileUtils.rm_rf(backup_repos_path) @@ -31,7 +32,7 @@ module Backup backup_restore = BackupRestore.new( progress, repository_type.repository_for(container), - backup_repos_path + @backup_repos_path ) case @type @@ -52,10 +53,6 @@ module Backup attr_reader :progress - def backup_repos_path - @backup_repos_path ||= File.join(Gitlab.config.backup.path, 'repositories') - end - class BackupRestore attr_accessor :progress, :repository, :backup_repos_path diff --git a/lib/backup/lfs.rb b/lib/backup/lfs.rb index 17f7b8bf8b0..e92f235a2d7 100644 --- a/lib/backup/lfs.rb +++ b/lib/backup/lfs.rb @@ -2,14 +2,11 @@ module Backup class Lfs < Backup::Files - attr_reader :progress - def initialize(progress) - @progress = progress - - super('lfs', Settings.lfs.storage_path) + super(progress, 'lfs', Settings.lfs.storage_path) end + override :human_name def human_name _('lfs objects') end diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index 5b393cf9477..6e90824fce2 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -2,43 +2,84 @@ module Backup class Manager - ARCHIVES_TO_BACKUP = %w[uploads builds artifacts pages lfs terraform_state registry packages].freeze - FOLDERS_TO_BACKUP = %w[repositories db].freeze FILE_NAME_SUFFIX = '_gitlab_backup.tar' + MANIFEST_NAME = 'backup_information.yml' + + TaskDefinition = Struct.new( + :destination_path, # Where the task should put its backup file/dir. + :destination_optional, # `true` if the destination might not exist on a successful backup. + :cleanup_path, # Path to remove after a successful backup. Uses `destination_path` when not specified. + :task, + keyword_init: true + ) attr_reader :progress - def initialize(progress) + def initialize(progress, definitions: nil) @progress = progress max_concurrency = ENV.fetch('GITLAB_BACKUP_MAX_CONCURRENCY', 1).to_i max_storage_concurrency = ENV.fetch('GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY', 1).to_i - - @tasks = { - 'db' => Database.new(progress), - 'repositories' => Repositories.new(progress, - strategy: repository_backup_strategy, - max_concurrency: max_concurrency, - max_storage_concurrency: max_storage_concurrency), - 'uploads' => Uploads.new(progress), - 'builds' => Builds.new(progress), - 'artifacts' => Artifacts.new(progress), - 'pages' => Pages.new(progress), - 'lfs' => Lfs.new(progress), - 'terraform_state' => TerraformState.new(progress), - 'registry' => Registry.new(progress), - 'packages' => Packages.new(progress) + force = ENV['force'] == 'yes' + incremental = Gitlab::Utils.to_boolean(ENV['INCREMENTAL'], default: false) + + @definitions = definitions || { + 'db' => TaskDefinition.new( + destination_path: 'db/database.sql.gz', + cleanup_path: 'db', + task: Database.new(progress, force: force) + ), + 'repositories' => TaskDefinition.new( + destination_path: 'repositories', + destination_optional: true, + task: Repositories.new(progress, + strategy: repository_backup_strategy(incremental), + max_concurrency: max_concurrency, + max_storage_concurrency: max_storage_concurrency) + ), + 'uploads' => TaskDefinition.new( + destination_path: 'uploads.tar.gz', + task: Uploads.new(progress) + ), + 'builds' => TaskDefinition.new( + destination_path: 'builds.tar.gz', + task: Builds.new(progress) + ), + 'artifacts' => TaskDefinition.new( + destination_path: 'artifacts.tar.gz', + task: Artifacts.new(progress) + ), + 'pages' => TaskDefinition.new( + destination_path: 'pages.tar.gz', + task: Pages.new(progress) + ), + 'lfs' => TaskDefinition.new( + destination_path: 'lfs.tar.gz', + task: Lfs.new(progress) + ), + 'terraform_state' => TaskDefinition.new( + destination_path: 'terraform_state.tar.gz', + task: TerraformState.new(progress) + ), + 'registry' => TaskDefinition.new( + destination_path: 'registry.tar.gz', + task: Registry.new(progress) + ), + 'packages' => TaskDefinition.new( + destination_path: 'packages.tar.gz', + task: Packages.new(progress) + ) }.freeze end def create - @tasks.keys.each do |task_name| + @definitions.keys.each do |task_name| run_create_task(task_name) end - write_info + write_backup_information - if ENV['SKIP'] && ENV['SKIP'].include?('tar') + if skipped?('tar') upload else pack @@ -54,21 +95,23 @@ module Backup end def run_create_task(task_name) - task = @tasks[task_name] + definition = @definitions[task_name] - puts_time "Dumping #{task.human_name} ... ".color(:blue) + build_backup_information + puts_time "Dumping #{definition.task.human_name} ... ".color(:blue) - unless task.enabled + unless definition.task.enabled puts_time "[DISABLED]".color(:cyan) return end - if ENV["SKIP"] && ENV["SKIP"].include?(task_name) + if skipped?(task_name) puts_time "[SKIPPED]".color(:cyan) return end - task.dump + definition.task.dump(File.join(Gitlab.config.backup.path, definition.destination_path)) + puts_time "done".color(:green) rescue Backup::DatabaseBackupError, Backup::FileBackupError => e @@ -77,42 +120,11 @@ module Backup def restore cleanup_required = unpack + read_backup_information verify_backup_version - unless skipped?('db') - begin - unless ENV['force'] == 'yes' - warning = <<-MSG.strip_heredoc - Be sure to stop Puma, Sidekiq, and any other process that - connects to the database before proceeding. For Omnibus - installs, see the following link for more information: - https://docs.gitlab.com/ee/raketasks/backup_restore.html#restore-for-omnibus-gitlab-installations - - Before restoring the database, we will remove all existing - tables to avoid future upgrade problems. Be aware that if you have - custom tables in the GitLab database these tables and all data will be - removed. - MSG - puts warning.color(:red) - Gitlab::TaskHelpers.ask_to_continue - puts 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'.color(:yellow) - sleep(5) - end - - # Drop all tables Load the schema to ensure we don't have any newer tables - # hanging out from a failed upgrade - puts_time 'Cleaning the database ... '.color(:blue) - Rake::Task['gitlab:db:drop_tables'].invoke - puts_time 'done'.color(:green) - run_restore_task('db') - rescue Gitlab::TaskAbortedByUserError - puts "Quitting...".color(:red) - exit 1 - end - end - - @tasks.except('db').keys.each do |task_name| - run_restore_task(task_name) unless skipped?(task_name) + @definitions.keys.each do |task_name| + run_restore_task(task_name) if !skipped?(task_name) && enabled_task?(task_name) end Rake::Task['gitlab:shell:setup'].invoke @@ -130,30 +142,71 @@ module Backup end def run_restore_task(task_name) - task = @tasks[task_name] + definition = @definitions[task_name] - puts_time "Restoring #{task.human_name} ... ".color(:blue) + read_backup_information + puts_time "Restoring #{definition.task.human_name} ... ".color(:blue) - unless task.enabled + unless definition.task.enabled puts_time "[DISABLED]".color(:cyan) return end - task.restore + warning = definition.task.pre_restore_warning + if warning.present? + puts_time warning.color(:red) + Gitlab::TaskHelpers.ask_to_continue + end + + definition.task.restore(File.join(Gitlab.config.backup.path, definition.destination_path)) + puts_time "done".color(:green) + + warning = definition.task.post_restore_warning + if warning.present? + puts_time warning.color(:red) + Gitlab::TaskHelpers.ask_to_continue + end + + rescue Gitlab::TaskAbortedByUserError + puts_time "Quitting...".color(:red) + exit 1 end - def write_info + private + + def read_backup_information + @backup_information ||= YAML.load_file(File.join(backup_path, MANIFEST_NAME)) + end + + def write_backup_information # Make sure there is a connection ActiveRecord::Base.connection.reconnect! Dir.chdir(backup_path) do - File.open("#{backup_path}/backup_information.yml", "w+") do |file| + File.open("#{backup_path}/#{MANIFEST_NAME}", "w+") do |file| file << backup_information.to_yaml.gsub(/^---\n/, '') end end end + def build_backup_information + @backup_information ||= { + db_version: ActiveRecord::Migrator.current_version.to_s, + backup_created_at: Time.now, + gitlab_version: Gitlab::VERSION, + tar_version: tar_version, + installation_type: Gitlab::INSTALLATION_TYPE, + skipped: ENV["SKIP"] + } + end + + def backup_information + raise Backup::Error, "#{MANIFEST_NAME} not yet loaded" unless @backup_information + + @backup_information + end + def pack Dir.chdir(backup_path) do # create archive @@ -182,8 +235,11 @@ module Backup upload = directory.files.create(create_attributes) if upload - progress.puts "done".color(:green) - upload + if upload.respond_to?(:encryption) && upload.encryption + progress.puts "done (encrypted with #{upload.encryption})".color(:green) + else + progress.puts "done".color(:green) + end else puts "uploading backup to #{remote_directory} failed".color(:red) raise Backup::Error, 'Backup failed' @@ -193,18 +249,19 @@ module Backup def cleanup progress.print "Deleting tmp directories ... " - backup_contents.each do |dir| - next unless File.exist?(File.join(backup_path, dir)) - - if FileUtils.rm_rf(File.join(backup_path, dir)) - progress.puts "done".color(:green) - else - puts "deleting tmp directory '#{dir}' failed".color(:red) - raise Backup::Error, 'Backup failed' - end + remove_backup_path(MANIFEST_NAME) + @definitions.each do |_, definition| + remove_backup_path(definition.cleanup_path || definition.destination_path) end end + def remove_backup_path(path) + return unless File.exist?(File.join(backup_path, path)) + + FileUtils.rm_rf(File.join(backup_path, path)) + progress.puts "done".color(:green) + end + def remove_tmp # delete tmp inside backups progress.print "Deleting backups/tmp ... " @@ -255,15 +312,15 @@ module Backup def verify_backup_version Dir.chdir(backup_path) do # restoring mismatching backups can lead to unexpected problems - if settings[:gitlab_version] != Gitlab::VERSION + if backup_information[:gitlab_version] != Gitlab::VERSION progress.puts(<<~HEREDOC.color(:red)) GitLab version mismatch: Your current GitLab version (#{Gitlab::VERSION}) differs from the GitLab version in the backup! Please switch to the following version and try again: - version: #{settings[:gitlab_version]} + version: #{backup_information[:gitlab_version]} HEREDOC progress.puts - progress.puts "Hint: git checkout v#{settings[:gitlab_version]}" + progress.puts "Hint: git checkout v#{backup_information[:gitlab_version]}" exit 1 end end @@ -319,13 +376,11 @@ module Backup end def skipped?(item) - settings[:skipped] && settings[:skipped].include?(item) || !enabled_task?(item) + backup_information[:skipped] && backup_information[:skipped].include?(item) end - private - def enabled_task?(task_name) - @tasks[task_name].enabled + @definitions[task_name].task.enabled end def backup_file?(file) @@ -333,7 +388,7 @@ module Backup end def non_tarred_backup? - File.exist?(File.join(backup_path, 'backup_information.yml')) + File.exist?(File.join(backup_path, MANIFEST_NAME)) end def backup_path @@ -380,19 +435,10 @@ module Backup end def backup_contents - folders_to_backup + archives_to_backup + ["backup_information.yml"] - end - - def archives_to_backup - ARCHIVES_TO_BACKUP.map { |name| (name + ".tar.gz") unless skipped?(name) }.compact - end - - def folders_to_backup - FOLDERS_TO_BACKUP.select { |name| !skipped?(name) && Dir.exist?(File.join(backup_path, name)) } - end - - def settings - @settings ||= YAML.load_file("backup_information.yml") + [MANIFEST_NAME] + @definitions.reject do |name, definition| + skipped?(name) || !enabled_task?(name) || + (definition.destination_optional && !File.exist?(File.join(backup_path, definition.destination_path))) + end.values.map(&:destination_path) end def tar_file @@ -403,17 +449,6 @@ module Backup end end - def backup_information - @backup_information ||= { - db_version: ActiveRecord::Migrator.current_version.to_s, - backup_created_at: Time.now, - gitlab_version: Gitlab::VERSION, - tar_version: tar_version, - installation_type: Gitlab::INSTALLATION_TYPE, - skipped: ENV["SKIP"] - } - end - def create_attributes attrs = { key: remote_target, @@ -447,11 +482,11 @@ module Backup Gitlab.config.backup.upload.connection&.provider&.downcase == 'google' end - def repository_backup_strategy + def repository_backup_strategy(incremental) if Feature.enabled?(:gitaly_backup, default_enabled: :yaml) max_concurrency = ENV['GITLAB_BACKUP_MAX_CONCURRENCY'].presence max_storage_concurrency = ENV['GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY'].presence - Backup::GitalyBackup.new(progress, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency) + Backup::GitalyBackup.new(progress, incremental: incremental, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency) else Backup::GitalyRpcBackup.new(progress) end diff --git a/lib/backup/packages.rb b/lib/backup/packages.rb index 037ff31fd9b..9384e007162 100644 --- a/lib/backup/packages.rb +++ b/lib/backup/packages.rb @@ -2,14 +2,11 @@ module Backup class Packages < Backup::Files - attr_reader :progress - def initialize(progress) - @progress = progress - - super('packages', Settings.packages.storage_path, excludes: ['tmp']) + super(progress, 'packages', Settings.packages.storage_path, excludes: ['tmp']) end + override :human_name def human_name _('packages') end diff --git a/lib/backup/pages.rb b/lib/backup/pages.rb index 724972d212d..ebed6820724 100644 --- a/lib/backup/pages.rb +++ b/lib/backup/pages.rb @@ -6,14 +6,11 @@ module Backup # if some of these files are still there, we don't need them in the backup LEGACY_PAGES_TMP_PATH = '@pages.tmp' - attr_reader :progress - def initialize(progress) - @progress = progress - - super('pages', Gitlab.config.pages.path, excludes: [LEGACY_PAGES_TMP_PATH]) + super(progress, 'pages', Gitlab.config.pages.path, excludes: [LEGACY_PAGES_TMP_PATH]) end + override :human_name def human_name _('pages') end diff --git a/lib/backup/registry.rb b/lib/backup/registry.rb index 7ba3a9e9c60..68ea635034d 100644 --- a/lib/backup/registry.rb +++ b/lib/backup/registry.rb @@ -2,18 +2,16 @@ module Backup class Registry < Backup::Files - attr_reader :progress - def initialize(progress) - @progress = progress - - super('registry', Settings.registry.path) + super(progress, 'registry', Settings.registry.path) end + override :human_name def human_name _('container registry images') end + override :enabled def enabled Gitlab.config.registry.enabled end diff --git a/lib/backup/repositories.rb b/lib/backup/repositories.rb index e7c3e869928..3633ebd661e 100644 --- a/lib/backup/repositories.rb +++ b/lib/backup/repositories.rb @@ -3,16 +3,20 @@ require 'yaml' module Backup - class Repositories + class Repositories < Task + extend ::Gitlab::Utils::Override + def initialize(progress, strategy:, max_concurrency: 1, max_storage_concurrency: 1) - @progress = progress + super(progress) + @strategy = strategy @max_concurrency = max_concurrency @max_storage_concurrency = max_storage_concurrency end - def dump - strategy.start(:create) + override :dump + def dump(path) + strategy.start(:create, path) # gitaly-backup is designed to handle concurrency on its own. So we want # to avoid entering the buggy concurrency code here when gitaly-backup @@ -50,8 +54,9 @@ module Backup strategy.finish! end - def restore - strategy.start(:restore) + override :restore + def restore(path) + strategy.start(:restore, path) enqueue_consecutive ensure @@ -61,17 +66,14 @@ module Backup restore_object_pools end - def enabled - true - end - + override :human_name def human_name _('repositories') end private - attr_reader :progress, :strategy, :max_concurrency, :max_storage_concurrency + attr_reader :strategy, :max_concurrency, :max_storage_concurrency def check_valid_storages! repository_storage_klasses.each do |klass| diff --git a/lib/backup/task.rb b/lib/backup/task.rb new file mode 100644 index 00000000000..15cd2aa64d3 --- /dev/null +++ b/lib/backup/task.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Backup + class Task + def initialize(progress) + @progress = progress + end + + # human readable task name used for logging + def human_name + raise NotImplementedError + end + + # dump task backup to `path` + def dump(path) + raise NotImplementedError + end + + # restore task backup from `path` + def restore(path) + raise NotImplementedError + end + + # a string returned here will be displayed to the user before calling #restore + def pre_restore_warning + end + + # a string returned here will be displayed to the user after calling #restore + def post_restore_warning + end + + # returns `true` when the task should be used + def enabled + true + end + + private + + attr_reader :progress + + def puts_time(msg) + progress.puts "#{Time.zone.now} -- #{msg}" + Gitlab::BackupLogger.info(message: "#{Rainbow.uncolor(msg)}") + end + end +end diff --git a/lib/backup/terraform_state.rb b/lib/backup/terraform_state.rb index be82793fe03..05f61d248be 100644 --- a/lib/backup/terraform_state.rb +++ b/lib/backup/terraform_state.rb @@ -2,14 +2,11 @@ module Backup class TerraformState < Backup::Files - attr_reader :progress - def initialize(progress) - @progress = progress - - super('terraform_state', Settings.terraform_state.storage_path, excludes: ['tmp']) + super(progress, 'terraform_state', Settings.terraform_state.storage_path, excludes: ['tmp']) end + override :human_name def human_name _('terraform states') end diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb index 7048a9a8ff5..700f2af4415 100644 --- a/lib/backup/uploads.rb +++ b/lib/backup/uploads.rb @@ -2,14 +2,11 @@ module Backup class Uploads < Backup::Files - attr_reader :progress - def initialize(progress) - @progress = progress - - super('uploads', File.join(Gitlab.config.uploads.storage_path, "uploads"), excludes: ['tmp']) + super(progress, 'uploads', File.join(Gitlab.config.uploads.storage_path, "uploads"), excludes: ['tmp']) end + override :human_name def human_name _('uploads') end |