diff options
Diffstat (limited to 'app/services/projects/container_repository/gitlab')
-rw-r--r-- | app/services/projects/container_repository/gitlab/cleanup_tags_service.rb | 81 | ||||
-rw-r--r-- | app/services/projects/container_repository/gitlab/delete_tags_service.rb | 15 |
2 files changed, 82 insertions, 14 deletions
diff --git a/app/services/projects/container_repository/gitlab/cleanup_tags_service.rb b/app/services/projects/container_repository/gitlab/cleanup_tags_service.rb new file mode 100644 index 00000000000..81bb94c867a --- /dev/null +++ b/app/services/projects/container_repository/gitlab/cleanup_tags_service.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Projects + module ContainerRepository + module Gitlab + class CleanupTagsService < CleanupTagsBaseService + include ::Projects::ContainerRepository::Gitlab::Timeoutable + + TAGS_PAGE_SIZE = 1000 + + def initialize(container_repository:, current_user: nil, params: {}) + super + @params = params.dup + end + + def execute + return error('access denied') unless can_destroy? + return error('invalid regex') unless valid_regex? + + with_timeout do |start_time, result| + container_repository.each_tags_page(page_size: TAGS_PAGE_SIZE) do |tags| + execute_for_tags(tags, result) + + raise TimeoutError if timeout?(start_time) + end + end + end + + private + + def execute_for_tags(tags, overall_result) + original_size = tags.size + + filter_out_latest!(tags) + filter_by_name!(tags) + + tags = filter_by_keep_n(tags) + tags = filter_by_older_than(tags) + + overall_result[:before_delete_size] += tags.size + overall_result[:original_size] += original_size + + result = delete_tags(tags) + + overall_result[:deleted_size] += result[:deleted]&.size + overall_result[:deleted] += result[:deleted] + overall_result[:status] = result[:status] unless overall_result[:status] == :error + end + + def with_timeout + result = { + original_size: 0, + before_delete_size: 0, + deleted_size: 0, + deleted: [] + } + + yield Time.zone.now, result + + result + rescue TimeoutError + result[:status] = :error + + result + end + + def filter_by_keep_n(tags) + partition_by_keep_n(tags).first + end + + def filter_by_older_than(tags) + partition_by_older_than(tags).first + end + + def pushed_at(tag) + tag.updated_at || tag.created_at + end + end + end + end +end diff --git a/app/services/projects/container_repository/gitlab/delete_tags_service.rb b/app/services/projects/container_repository/gitlab/delete_tags_service.rb index 81cef554dec..530cf87c338 100644 --- a/app/services/projects/container_repository/gitlab/delete_tags_service.rb +++ b/app/services/projects/container_repository/gitlab/delete_tags_service.rb @@ -6,10 +6,7 @@ module Projects class DeleteTagsService include BaseServiceUtility include ::Gitlab::Utils::StrongMemoize - - DISABLED_TIMEOUTS = [nil, 0].freeze - - TimeoutError = Class.new(StandardError) + include ::Projects::ContainerRepository::Gitlab::Timeoutable def initialize(container_repository, tag_names) @container_repository = container_repository @@ -44,16 +41,6 @@ module Projects @deleted_tags.any? ? success(deleted: @deleted_tags) : error('could not delete tags') end - - def timeout?(start_time) - return false if service_timeout.in?(DISABLED_TIMEOUTS) - - (Time.zone.now - start_time) > service_timeout - end - - def service_timeout - ::Gitlab::CurrentSettings.current_application_settings.container_registry_delete_tags_service_timeout - end end end end |