1# frozen_string_literal: true 2 3class ImportExportUpload < ApplicationRecord 4 include WithUploads 5 include ObjectStorage::BackgroundMove 6 7 belongs_to :project 8 belongs_to :group 9 10 # These hold the project Import/Export archives (.tar.gz files) 11 mount_uploader :import_file, ImportExportUploader 12 mount_uploader :export_file, ImportExportUploader 13 14 # This causes CarrierWave v1 and v3 (but not v2) to upload the file to 15 # object storage *after* the database entry has been committed to the 16 # database. This avoids idling in a transaction. 17 if Gitlab::Utils.to_boolean(ENV.fetch('ENABLE_STORE_EXPORT_FILE_AFTER_COMMIT', true)) 18 skip_callback :save, :after, :store_export_file! 19 set_callback :commit, :after, :store_export_file! 20 end 21 22 scope :updated_before, ->(date) { where('updated_at < ?', date) } 23 scope :with_export_file, -> { where.not(export_file: nil) } 24 25 def retrieve_upload(_identifier, paths) 26 Upload.find_by(model: self, path: paths) 27 end 28 29 def export_file_exists? 30 !!carrierwave_export_file 31 end 32 33 # This checks if the export archive is actually stored on disk. It 34 # requires a HEAD request if object storage is used. 35 def export_archive_exists? 36 !!carrierwave_export_file&.exists? 37 # Handle any HTTP unexpected error 38 # https://github.com/excon/excon/blob/bbb5bd791d0bb2251593b80e3bce98dbec6e8f24/lib/excon/error.rb#L129-L169 39 rescue Excon::Error => e 40 # The HEAD request will fail with a 403 Forbidden if the file does not 41 # exist, and the user does not have permission to list the object 42 # storage bucket. 43 Gitlab::ErrorTracking.track_exception(e) 44 false 45 end 46 47 private 48 49 def carrierwave_export_file 50 export_file&.file 51 end 52end 53