2020-04-08 14:13:33 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Gitlab
|
|
|
|
module ImportExport
|
|
|
|
module Project
|
|
|
|
class TreeSaver
|
2022-06-21 17:19:12 +05:30
|
|
|
include DurationMeasuring
|
|
|
|
|
2020-04-08 14:13:33 +05:30
|
|
|
attr_reader :full_path
|
|
|
|
|
2022-08-27 11:52:29 +05:30
|
|
|
def initialize(project:, current_user:, shared:, params: {}, logger: Gitlab::Export::Logger)
|
2020-04-08 14:13:33 +05:30
|
|
|
@params = params
|
|
|
|
@project = project
|
|
|
|
@current_user = current_user
|
|
|
|
@shared = shared
|
2021-12-11 22:18:48 +05:30
|
|
|
@logger = logger
|
2020-04-08 14:13:33 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def save
|
2022-06-21 17:19:12 +05:30
|
|
|
with_duration_measuring do
|
|
|
|
stream_export
|
2020-04-08 14:13:33 +05:30
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
true
|
|
|
|
end
|
2021-06-08 01:23:25 +05:30
|
|
|
rescue StandardError => e
|
2020-04-08 14:13:33 +05:30
|
|
|
@shared.error(e)
|
|
|
|
false
|
|
|
|
ensure
|
|
|
|
json_writer&.close
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2021-12-11 22:18:48 +05:30
|
|
|
def stream_export
|
|
|
|
on_retry = proc do |exception, try, elapsed_time, next_interval|
|
|
|
|
@logger.info(
|
|
|
|
message: "Project export retry triggered from streaming",
|
|
|
|
'error.class': exception.class,
|
|
|
|
'error.message': exception.message,
|
|
|
|
try_count: try,
|
|
|
|
elapsed_time_s: elapsed_time,
|
|
|
|
wait_to_retry_s: next_interval,
|
|
|
|
project_name: @project.name,
|
|
|
|
project_id: @project.id
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
serializer = ImportExport::Json::StreamingSerializer.new(
|
|
|
|
exportable,
|
|
|
|
reader.project_tree,
|
|
|
|
json_writer,
|
2022-08-27 11:52:29 +05:30
|
|
|
exportable_path: "project",
|
2022-10-11 01:57:18 +05:30
|
|
|
logger: @logger,
|
|
|
|
current_user: @current_user
|
2021-12-11 22:18:48 +05:30
|
|
|
)
|
|
|
|
|
|
|
|
Retriable.retriable(on: Net::OpenTimeout, on_retry: on_retry) do
|
|
|
|
serializer.execute
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-04-08 14:13:33 +05:30
|
|
|
def reader
|
|
|
|
@reader ||= Gitlab::ImportExport::Reader.new(shared: @shared)
|
|
|
|
end
|
|
|
|
|
|
|
|
def exportable
|
2021-01-03 14:25:43 +05:30
|
|
|
@project.present(**exportable_params)
|
2020-04-08 14:13:33 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def exportable_params
|
|
|
|
params = {
|
|
|
|
presenter_class: presenter_class,
|
|
|
|
current_user: @current_user
|
|
|
|
}
|
|
|
|
params[:override_description] = @params[:description] if @params[:description].present?
|
|
|
|
params
|
|
|
|
end
|
|
|
|
|
|
|
|
def presenter_class
|
|
|
|
Projects::ImportExport::ProjectExportPresenter
|
|
|
|
end
|
2020-04-22 19:07:51 +05:30
|
|
|
|
|
|
|
def json_writer
|
|
|
|
@json_writer ||= begin
|
2022-07-16 23:28:13 +05:30
|
|
|
if ::Feature.enabled?(:project_export_as_ndjson, @project.namespace)
|
2020-04-22 19:07:51 +05:30
|
|
|
full_path = File.join(@shared.export_path, 'tree')
|
2021-09-04 01:27:46 +05:30
|
|
|
Gitlab::ImportExport::Json::NdjsonWriter.new(full_path)
|
2020-04-22 19:07:51 +05:30
|
|
|
else
|
|
|
|
full_path = File.join(@shared.export_path, ImportExport.project_filename)
|
2021-09-04 01:27:46 +05:30
|
|
|
Gitlab::ImportExport::Json::LegacyWriter.new(full_path, allowed_path: 'project')
|
2020-04-22 19:07:51 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-04-08 14:13:33 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|