Skip to content
代码片段 群组 项目
提交 7440f3a8 编辑于 作者: Gabriel Mazetto's avatar Gabriel Mazetto
浏览文件

Introduce a BackupExecutor and SourceContext

上级 911db940
No related branches found
No related tags found
1 合并请求!2419Fix TanukiBot spec relying on outdated code
......@@ -7,11 +7,13 @@ module Gitlab
module Backup
# GitLab Backup CLI
module Cli
autoload :BackupExecutor, 'gitlab/backup/cli/backup_executor'
autoload :Commands, 'gitlab/backup/cli/commands'
autoload :Dependencies, 'gitlab/backup/cli/dependencies'
autoload :BackupMetadata, 'gitlab/backup/cli/backup_metadata'
autoload :Output, 'gitlab/backup/cli/output'
autoload :Runner, 'gitlab/backup/cli/runner'
autoload :SourceContext, 'gitlab/backup/cli/source_context'
autoload :Shell, 'gitlab/backup/cli/shell'
autoload :Tasks, 'gitlab/backup/cli/tasks'
autoload :Utils, 'gitlab/backup/cli/utils'
......
# frozen_string_literal: true
module Gitlab
module Backup
module Cli
# This is responsible for executing a Backup operation
#
# A Backup Executor handles the creation and deletion of
# temporary environment necessary for a backup to happen
#
# It also allows for multiple backups to happen in parallel
# without one overwriting data from another
class BackupExecutor
attr_reader :context, :metadata, :workdir, :archive_directory
# @param [Gitlab::Backup::Cli::SourceContext] context
def initialize(context:)
@context = context
@metadata = build_metadata
@workdir = create_temporary_workdir!
@archive_directory = context.backup_basedir.join(metadata.backup_id)
end
def execute
execute_all_tasks
archive!
end
# At the end of a successful backup, call this to release temporary resources
def release!
FileUtils.rm_rf(workdir)
end
private
def build_metadata
@metadata = Gitlab::Backup::Cli::BackupMetadata.build(gitlab_version: context.gitlab_version)
end
def execute_all_tasks
# TODO: when we migrate targets to the new codebase, recreate options to have only what we need here
# https://gitlab.com/gitlab-org/gitlab/-/issues/454906
options = ::Backup::Options.new
Gitlab::Backup::Cli::Tasks.all.each do |t|
task = t.new(context: context, options: options)
Gitlab::Backup::Cli::Output.info("Executing Backup of #{task.human_name}...")
duration = measure_duration do
task.backup!(workdir, metadata.backup_id)
end
Gitlab::Backup::Cli::Output.success("Finished Backup of #{task.human_name}! (#{duration.in_seconds}s)")
end
end
def archive!
# TODO: create a single-file archive instead of moving everything to a directory
# https://gitlab.com/gitlab-org/gitlab/-/issues/454832
FileUtils.mkdir(archive_directory)
workdir.glob('*').each { |entry| FileUtils.mv(entry, archive_directory) }
end
# @return [Pathname] temporary directory
def create_temporary_workdir!
# Ensure base directory exists
FileUtils.mkdir_p(context.backup_basedir)
Pathname(Dir.mktmpdir('backup', context.backup_basedir))
end
def measure_duration
start = Time.now
yield
ActiveSupport::Duration.build(Time.now - start)
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Backup
module Cli
# This context is equivalent to a Source Install or GDK instance
#
# Any specific information from the GitLab installation will be
# automatically discovered from the current machine
class SourceContext
def gitlab_version
# TODO: decouple from Rails codebase
Gitlab::VERSION
end
def backup_basedir
# TODO: decouple from Rails codebase, load from gitlab.yml file
Rails.root.join('tmp/backups')
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Backup::Cli::BackupExecutor do
let(:context) { build_fake_context }
subject(:executor) { described_class.new(context: context) }
after do
executor.release!
end
describe '#initialize' do
it 'creates a workdir' do
expect(executor.workdir).to be_a(Pathname)
expect(executor.workdir).to be_directory
end
it 'initializes metadata' do
expect(executor.metadata).to be_a(Gitlab::Backup::Cli::BackupMetadata)
end
end
describe '#release!' do
it 'removes the workdir' do
expect { executor.release! }.to change { executor.workdir.exist? }.from(true).to(false)
end
end
end
# frozen_string_literal: true
FakeContext = Struct.new(:gitlab_version, :backup_basedir, keyword_init: true)
def spec_path
Pathname.new(__dir__).join('..').expand_path
end
......@@ -11,3 +13,7 @@ def temp_path
def stub_env(var, return_value)
stub_const('ENV', ENV.to_hash.merge(var => return_value))
end
def build_fake_context
FakeContext.new(gitlab_version: '16.10', backup_basedir: temp_path.join('backups'))
end
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册