2020-04-08 14:13:33 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Gitlab
|
|
|
|
module ImportExport
|
|
|
|
module Project
|
|
|
|
class ImportTask < BaseTask
|
|
|
|
def import
|
|
|
|
show_import_start_message
|
|
|
|
|
|
|
|
run_isolated_sidekiq_job
|
|
|
|
|
|
|
|
show_import_failures_count
|
|
|
|
|
|
|
|
return error(project.import_state.last_error) if project.import_state&.last_error
|
|
|
|
return error(project.errors.full_messages.to_sentence) if project.errors.any?
|
|
|
|
|
|
|
|
success('Done!')
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
# We want to ensure that all Sidekiq jobs are executed
|
|
|
|
# synchronously as part of that process.
|
|
|
|
# This ensures that all expensive operations do not escape
|
|
|
|
# to general Sidekiq clusters/nodes.
|
|
|
|
def with_isolated_sidekiq_job
|
|
|
|
Sidekiq::Testing.fake! do
|
|
|
|
with_request_store do
|
|
|
|
# If you are attempting to import a large project into a development environment,
|
|
|
|
# you may see Gitaly throw an error about too many calls or invocations.
|
|
|
|
# This is due to a n+1 calls limit being set for development setups (not enforced in production)
|
|
|
|
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24475#note_283090635
|
|
|
|
# For development setups, this code-path will be excluded from n+1 detection.
|
|
|
|
::Gitlab::GitalyClient.allow_n_plus_1_calls do
|
2020-05-24 23:13:21 +05:30
|
|
|
yield
|
2020-04-08 14:13:33 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def run_isolated_sidekiq_job
|
|
|
|
with_isolated_sidekiq_job do
|
|
|
|
@project = create_project
|
|
|
|
|
|
|
|
execute_sidekiq_job
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_project
|
|
|
|
# We are disabling ObjectStorage for `import`
|
|
|
|
# as it is too slow to handle big archives:
|
|
|
|
# 1. DB transaction timeouts on upload
|
|
|
|
# 2. Download of archive before unpacking
|
|
|
|
disable_upload_object_storage do
|
|
|
|
service = Projects::GitlabProjectsImportService.new(
|
|
|
|
current_user,
|
2020-05-24 23:13:21 +05:30
|
|
|
import_params
|
2020-04-08 14:13:33 +05:30
|
|
|
)
|
|
|
|
|
|
|
|
service.execute
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute_sidekiq_job
|
|
|
|
Sidekiq::Worker.drain_all
|
|
|
|
end
|
|
|
|
|
|
|
|
def full_path
|
|
|
|
"#{namespace.full_path}/#{project_path}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def show_import_start_message
|
|
|
|
logger.info "Importing GitLab export: #{file_path} into GitLab" \
|
|
|
|
" #{full_path}" \
|
|
|
|
" as #{current_user.name}"
|
|
|
|
end
|
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
def import_params
|
|
|
|
{
|
|
|
|
namespace_id: namespace.id,
|
|
|
|
path: project_path,
|
|
|
|
file: File.open(file_path)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2020-04-08 14:13:33 +05:30
|
|
|
def show_import_failures_count
|
|
|
|
return unless project.import_failures.exists?
|
|
|
|
|
|
|
|
logger.info "Total number of not imported relations: #{project.import_failures.count}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|