Commit 456dcaf1 authored by Kassio Borges's avatar Kassio Borges

Github Importer: Validate repository size before importing

Currently the size of the github repository is not validated before
starting the importing process. This leads to a slow feedback loop where
the failure happens much later in the process. To improve the feedback
loop and give the user better experience the validation is now done
before the import starts. If the repository to be imported is larger
than the namespace or application limits an error message expressing the
repository size and the limit size is shown.

Related to: https://gitlab.com/gitlab-org/gitlab/-/issues/215057
parent d54e6dc0
......@@ -2,6 +2,9 @@
module Import
class GithubService < Import::BaseService
include ActiveSupport::NumberHelper
include Gitlab::Utils::StrongMemoize
attr_accessor :client
attr_reader :params, :current_user
......@@ -14,6 +17,10 @@ module Import
return error(_('This namespace has already been taken! Please choose another one.'), :unprocessable_entity)
end
if oversized?
return error(oversize_error_message, :unprocessable_entity)
end
project = create_project(access_params, provider)
if project.persisted?
......@@ -32,7 +39,8 @@ module Import
target_namespace,
current_user,
type: provider,
**access_params).execute(extra_project_attrs)
**access_params
).execute(extra_project_attrs)
end
def repo
......@@ -55,6 +63,30 @@ module Import
{}
end
def oversized?
repository_size_limit > 0 && repo.size > repository_size_limit
end
def oversize_error_message
_('"%{repository_name}" size (%{repository_size}) is larger than the limit of %{limit}.') % {
repository_name: repo.name,
repository_size: number_to_human_size(repo.size),
limit: number_to_human_size(repository_size_limit)
}
end
def repository_size_limit
strong_memoize :repository_size_limit do
namespace_limit = target_namespace.repository_size_limit.to_i
if namespace_limit > 0
namespace_limit
else
Gitlab::CurrentSettings.repository_size_limit.to_i
end
end
end
def authorized?
can?(current_user, :create_projects, target_namespace)
end
......
---
title: 'Github Importer: Validate repository size before importing'
merge_request: 54449
author:
type: changed
......@@ -74,6 +74,9 @@ msgstr ""
msgid "\"%{path}\" did not exist on \"%{ref}\""
msgstr ""
msgid "\"%{repository_name}\" size (%{repository_size}) is larger than the limit of %{limit}."
msgstr ""
msgid "\"el\" parameter is required for createInstance()"
msgstr ""
......
......@@ -54,6 +54,62 @@ RSpec.describe Import::GithubService do
expect { subject.execute(access_params, :github) }.to raise_error(exception)
end
context 'repository size validation' do
let(:repository_double) { double(name: 'repository', size: 99) }
before do
expect(client).to receive(:repository).and_return(repository_double)
allow_next_instance_of(Gitlab::LegacyGithubImport::ProjectCreator) do |creator|
allow(creator).to receive(:execute).and_return(double(persisted?: true))
end
end
context 'when there is no repository size limit defined' do
it 'skips the check and succeeds' do
expect(subject.execute(access_params, :github)).to include(status: :success)
end
end
context 'when the target namespace repository size limit is defined' do
let_it_be(:group) { create(:group, repository_size_limit: 100) }
before do
params[:target_namespace] = group.full_path
end
it 'succeeds when the repository is smaller than the limit' do
expect(subject.execute(access_params, :github)).to include(status: :success)
end
it 'returns error when the repository is larger than the limit' do
allow(repository_double).to receive(:size).and_return(101)
expect(subject.execute(access_params, :github)).to include(size_limit_error)
end
end
context 'when target namespace repository limit is not defined' do
let_it_be(:group) { create(:group) }
before do
stub_application_setting(repository_size_limit: 100)
end
context 'when application size limit is defined' do
it 'succeeds when the repository is smaller than the limit' do
expect(subject.execute(access_params, :github)).to include(status: :success)
end
it 'returns error when the repository is larger than the limit' do
allow(repository_double).to receive(:size).and_return(101)
expect(subject.execute(access_params, :github)).to include(size_limit_error)
end
end
end
end
end
context 'when remove_legacy_github_client feature flag is enabled' do
......@@ -71,4 +127,12 @@ RSpec.describe Import::GithubService do
include_examples 'handles errors', Gitlab::LegacyGithubImport::Client
end
def size_limit_error
{
status: :error,
http_status: :unprocessable_entity,
message: '"repository" size (101 Bytes) is larger than the limit of 100 Bytes.'
}
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment