Class: Projects::ContainerRepository::ThirdParty::DeleteTagsService

Inherits:
Object
  • Object
show all
Includes:
BaseServiceUtility
Defined in:
app/services/projects/container_repository/third_party/delete_tags_service.rb

Instance Method Summary collapse

Methods included from BaseServiceUtility

#deny_visibility_level, #event_service, #log_error, #log_info, #notification_service, #system_hook_service, #todo_service, #visibility_level

Methods included from Gitlab::Allowable

#can?

Constructor Details

#initialize(container_repository, tag_names) ⇒ DeleteTagsService

Returns a new instance of DeleteTagsService.


9
10
11
12
# File 'app/services/projects/container_repository/third_party/delete_tags_service.rb', line 9

def initialize(container_repository, tag_names)
  @container_repository = container_repository
  @tag_names = tag_names
end

Instance Method Details

#executeObject

Replace a tag on the registry with a dummy tag. This is a hack as the registry doesn't support deleting individual tags. This code effectively pushes a dummy image and assigns the tag to it. This way when the tag is deleted only the dummy image is affected. This is used to preserve compatibility with third-party registries that don't support fast delete. See gitlab.com/gitlab-org/gitlab/issues/15737 for a discussion


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'app/services/projects/container_repository/third_party/delete_tags_service.rb', line 21

def execute
  return success(deleted: []) if @tag_names.empty?

  # generates the blobs for the dummy image
  dummy_manifest = @container_repository.client.generate_empty_manifest(@container_repository.path)
  return error('could not generate manifest') if dummy_manifest.nil?

  deleted_tags = replace_tag_manifests(dummy_manifest)

  # Deletes the dummy image
  # All created tag digests are the same since they all have the same dummy image.
  # a single delete is sufficient to remove all tags with it
  if deleted_tags.any? && @container_repository.delete_tag_by_digest(deleted_tags.each_value.first)
    success(deleted: deleted_tags.keys)
  else
    error("could not delete tags: #{@tag_names.join(', ')}".truncate(1000))
  end
end