debian-mirror-gitlab/lib/gitlab/cleanup/orphan_lfs_file_references.rb

73 lines
1.9 KiB
Ruby
Raw Normal View History

2020-04-22 19:07:51 +05:30
# frozen_string_literal: true
module Gitlab
module Cleanup
class OrphanLfsFileReferences
include Gitlab::Utils::StrongMemoize
attr_reader :project, :dry_run, :logger, :limit
DEFAULT_REMOVAL_LIMIT = 1000
def initialize(project, dry_run: true, logger: nil, limit: nil)
@project = project
@dry_run = dry_run
2020-11-24 15:15:51 +05:30
@logger = logger || Gitlab::AppLogger
2020-04-22 19:07:51 +05:30
@limit = limit
end
def run!
log_info("Looking for orphan LFS files for project #{project.name_with_namespace}")
2021-01-03 14:25:43 +05:30
if project.lfs_objects.empty?
log_info("Project #{project.name_with_namespace} is linked to 0 LFS objects. Nothing to do")
return
end
2020-04-22 19:07:51 +05:30
remove_orphan_references
end
private
def remove_orphan_references
2020-11-24 15:15:51 +05:30
invalid_references = project.lfs_objects_projects.lfs_object_in(orphan_objects)
2020-04-22 19:07:51 +05:30
if dry_run
log_info("Found invalid references: #{invalid_references.count}")
else
count = 0
invalid_references.each_batch(of: limit || DEFAULT_REMOVAL_LIMIT) do |relation|
count += relation.delete_all
end
2020-05-24 23:13:21 +05:30
ProjectCacheWorker.perform_async(project.id, [], [:lfs_objects_size])
2020-04-22 19:07:51 +05:30
log_info("Removed invalid references: #{count}")
end
end
2020-11-24 15:15:51 +05:30
def orphan_objects
# Get these first so racing with a git push can't remove any LFS objects
oids = project.lfs_objects_oids
2020-04-22 19:07:51 +05:30
2020-11-24 15:15:51 +05:30
repos = [
project.repository,
project.design_repository,
project.wiki.repository
].select(&:exists?)
2020-04-22 19:07:51 +05:30
2020-11-24 15:15:51 +05:30
repos.flat_map do |repo|
oids -= repo.gitaly_blob_client.get_all_lfs_pointers.map(&:lfs_oid)
2020-04-22 19:07:51 +05:30
end
2020-11-24 15:15:51 +05:30
# The remaining OIDs are not used by any repository, so are orphans
LfsObject.for_oids(oids)
2020-04-22 19:07:51 +05:30
end
def log_info(msg)
logger.info("#{'[DRY RUN] ' if dry_run}#{msg}")
end
end
end
end