From 39d4557523476a3cc5dd3b5e50bc6ccde56e3ae5 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Fri, 17 Dec 2021 15:41:16 +0000 Subject: [PATCH 1/2] really delete cached attachments --- app/models/attachment.rb | 13 +++++++++++++ lib/tasks/attachments.rake | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 2d4ce1dbba..db409e877c 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -285,6 +285,19 @@ class Attachment < ApplicationRecord end end + ## + # Deletes locally cached files. This is mostly relevant for remote attachments + # but would also apply for local attachments if things such as carrierwave + # filters were used. + # + # @param age_in_seconds [Integer] Delete all cached files older than this many seconds. + def self.clean_cached_files!(age_in_seconds: 60 * 60 * 24) + uploader = OpenProject::Configuration.file_uploader + cache_storage = uploader.cache_storage + + cache_storage.new(uploader.new).clean_cache! age_in_seconds + end + def pending_direct_upload? digest == "" && downloads == -1 end diff --git a/lib/tasks/attachments.rake b/lib/tasks/attachments.rake index 79bdd1ba1a..ad68151f46 100644 --- a/lib/tasks/attachments.rake +++ b/lib/tasks/attachments.rake @@ -31,7 +31,7 @@ namespace :attachments do desc 'Clear all attachments created before yesterday' task clear: [:environment] do - CarrierWave.clean_cached_files! + Attachment.clean_cached_files! end desc 'Copies all attachments from the current to the given storage.' From 338861eb8c4657f37a96a51503ddac62b79a8998 Mon Sep 17 00:00:00 2001 From: Markus Kahl Date: Fri, 17 Dec 2021 15:43:19 +0000 Subject: [PATCH 2/2] delete cached attachments immediately after backup --- app/workers/backup_job.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/workers/backup_job.rb b/app/workers/backup_job.rb index 5819218d34..3c3f13f67e 100644 --- a/app/workers/backup_job.rb +++ b/app/workers/backup_job.rb @@ -142,6 +142,9 @@ class BackupJob < ::ApplicationJob end def create_backup_archive!(file_name:, db_dump_file_name:, attachments: attachments_to_include) + paths_to_clean = [] + clean_up = OpenProject::Configuration.remote_storage? + Zip::File.open(file_name, Zip::File::CREATE) do |zipfile| attachments.each do |attachment| # If an attachment is destroyed on disk, skip i @@ -151,16 +154,33 @@ class BackupJob < ::ApplicationJob path = diskfile.path zipfile.add "attachment/file/#{attachment.id}/#{attachment[:file]}", path + + paths_to_clean << get_cache_folder_path(attachment) if clean_up && a.file.cached? end zipfile.get_output_stream("openproject.sql") { |f| f.write File.read(db_dump_file_name) } end + # delete locally cached files that were downloaded just for the backup + paths_to_clean.each do |path| + FileUtils.rm_rf path + end + @archived = true file_name end + def get_cache_folder_path(attachment) + # expecting paths like /tmp/op_uploaded_files/1639754082-3468-0002-0911/file.ext + # just making extra sure so we don't delete anything wrong later on + unless attachment.diskfile.path =~ /#{attachment.file.cache_dir}\/[^\/]+\/[^\/]+/ + raise "Unexpected cache path for attachment ##{attachment.id}: #{attachment.diskfile}" + end + + Pathname(attachment.disfile.path).parent.to_s + end + def attachments_to_include return Attachment.none if skip_attachments?