debian-mirror-gitlab/lib/backup/gitaly_backup.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

119 lines
3.6 KiB
Ruby
Raw Normal View History

2021-09-04 01:27:46 +05:30
# frozen_string_literal: true
module Backup
# Backup and restores repositories using gitaly-backup
2022-03-02 08:16:31 +05:30
#
# gitaly-backup can work in parallel and accepts a list of repositories
# through input pipe using a specific json format for both backup and restore
2021-09-04 01:27:46 +05:30
class GitalyBackup
2022-03-02 08:16:31 +05:30
# @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)
2022-05-07 20:08:51 +05:30
def initialize(progress, max_parallelism: nil, storage_parallelism: nil, incremental: false, backup_id: nil)
2021-09-04 01:27:46 +05:30
@progress = progress
2022-03-02 08:16:31 +05:30
@max_parallelism = max_parallelism
@storage_parallelism = storage_parallelism
2022-05-07 20:08:51 +05:30
@incremental = incremental
2021-09-04 01:27:46 +05:30
end
2022-06-21 17:19:12 +05:30
def start(type, backup_repos_path, backup_id: nil)
2021-09-04 01:27:46 +05:30
raise Error, 'already started' if started?
2022-07-16 23:28:13 +05:30
if type == :create && !incremental?
FileUtils.rm_rf(backup_repos_path)
end
2021-09-04 01:27:46 +05:30
command = case type
when :create
'create'
when :restore
'restore'
else
raise Error, "unknown backup type: #{type}"
end
2022-08-27 11:52:29 +05:30
args = ['-layout', 'pointer']
2022-03-02 08:16:31 +05:30
args += ['-parallel', @max_parallelism.to_s] if @max_parallelism
args += ['-parallel-storage', @storage_parallelism.to_s] if @storage_parallelism
2022-08-27 11:52:29 +05:30
if type == :create
args += ['-incremental'] if incremental?
args += ['-id', backup_id] if backup_id
2022-05-07 20:08:51 +05:30
end
2021-09-30 23:02:18 +05:30
2022-03-02 08:16:31 +05:30
@input_stream, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args)
2021-10-27 15:23:28 +05:30
@out_reader = Thread.new do
IO.copy_stream(stdout, @progress)
end
2021-09-04 01:27:46 +05:30
end
2022-03-02 08:16:31 +05:30
def finish!
2021-09-04 01:27:46 +05:30
return unless started?
2022-03-02 08:16:31 +05:30
@input_stream.close
2021-10-27 15:23:28 +05:30
[@thread, @out_reader].each(&:join)
status = @thread.value
2021-09-04 01:27:46 +05:30
2021-10-27 15:23:28 +05:30
@thread = nil
2021-09-04 01:27:46 +05:30
raise Error, "gitaly-backup exit status #{status.exitstatus}" if status.exitstatus != 0
end
def enqueue(container, repo_type)
raise Error, 'not started' unless started?
repository = repo_type.repository_for(container)
2022-03-02 08:16:31 +05:30
schedule_backup_job(repository, always_create: repo_type.project?)
2021-09-04 01:27:46 +05:30
end
2021-09-30 23:02:18 +05:30
private
2021-09-04 01:27:46 +05:30
2022-07-16 23:28:13 +05:30
def incremental?
@incremental
end
2022-03-02 08:16:31 +05:30
# Schedule a new backup job through a non-blocking JSON based pipe protocol
#
# @see https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/gitaly-backup.md
def schedule_backup_job(repository, always_create:)
json_job = {
storage_name: repository.storage,
relative_path: repository.relative_path,
gl_project_path: repository.gl_project_path,
always_create: always_create
}.to_json
@input_stream.puts(json_job)
end
2023-05-27 22:25:52 +05:30
def gitaly_servers
Gitlab.config.repositories.storages.keys.index_with do |storage_name|
Gitlab::GitalyClient.connection_data(storage_name)
end
end
def gitaly_servers_encoded
Base64.strict_encode64(Gitlab::Json.dump(gitaly_servers))
end
2021-11-18 22:05:49 +05:30
def build_env
{
2022-08-13 15:12:31 +05:30
'SSL_CERT_FILE' => Gitlab::X509::Certificate.default_cert_file,
2023-05-27 22:25:52 +05:30
'SSL_CERT_DIR' => Gitlab::X509::Certificate.default_cert_dir,
'GITALY_SERVERS' => gitaly_servers_encoded
2021-11-18 22:05:49 +05:30
}.merge(ENV)
end
2021-09-04 01:27:46 +05:30
def started?
2021-10-27 15:23:28 +05:30
@thread.present?
2021-09-04 01:27:46 +05:30
end
def bin_path
2022-06-21 17:19:12 +05:30
raise Error, 'gitaly-backup binary not found and gitaly_backup_path is not configured' unless Gitlab.config.backup.gitaly_backup_path.present?
2021-09-30 23:02:18 +05:30
File.absolute_path(Gitlab.config.backup.gitaly_backup_path)
2021-09-04 01:27:46 +05:30
end
end
end