mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FIX: automatic backup uploads to S3 when using a region
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
require "s3_helper"
|
||||
|
||||
class Backup
|
||||
include UrlHelper
|
||||
include ActiveModel::SerializerSupport
|
||||
@@ -38,14 +40,26 @@ class Backup
|
||||
remove_from_s3 if SiteSetting.enable_s3_backups?
|
||||
end
|
||||
|
||||
def s3_bucket
|
||||
return @s3_bucket if @s3_bucket
|
||||
raise Discourse::SiteSettingMissing.new("s3_backup_bucket") if SiteSetting.s3_backup_bucket.blank?
|
||||
@s3_bucket = SiteSetting.s3_backup_bucket.downcase
|
||||
end
|
||||
|
||||
def s3
|
||||
return @s3_helper if @s3_helper
|
||||
@s3_helper = S3Helper.new(s3_bucket)
|
||||
end
|
||||
|
||||
def upload_to_s3
|
||||
return unless fog_directory
|
||||
fog_directory.files.create(key: @filename, public: false, body: File.read(@path))
|
||||
return unless s3
|
||||
file = File.read(@path)
|
||||
s3.upload(file, @filename)
|
||||
end
|
||||
|
||||
def remove_from_s3
|
||||
return unless fog
|
||||
fog.delete_object(SiteSetting.s3_backup_bucket, @filename)
|
||||
return unless s3
|
||||
s3.remove(@filename)
|
||||
end
|
||||
|
||||
def self.base_directory
|
||||
@@ -67,40 +81,8 @@ class Backup
|
||||
def self.remove_old
|
||||
return if Rails.env.development?
|
||||
all_backups = Backup.all
|
||||
return unless all_backups.size > SiteSetting.maximum_backups
|
||||
return if all_backups.size <= SiteSetting.maximum_backups
|
||||
all_backups[SiteSetting.maximum_backups..-1].each(&:remove)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def s3_options
|
||||
options = {
|
||||
provider: 'AWS',
|
||||
region: SiteSetting.s3_region.blank? ? "us-east-1" : SiteSetting.s3_region,
|
||||
}
|
||||
if (SiteSetting.s3_use_iam_profile.present?)
|
||||
options.merge!(:use_iam_profile => true)
|
||||
else
|
||||
options.merge!(:aws_access_key_id => SiteSetting.s3_access_key_id,
|
||||
:aws_secret_access_key => SiteSetting.s3_secret_access_key)
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
def fog
|
||||
return @fog if @fog
|
||||
return unless ((SiteSetting.s3_access_key_id.present? &&
|
||||
SiteSetting.s3_secret_access_key.present?) ||
|
||||
SiteSetting.s3_use_iam_profile.present?) &&
|
||||
SiteSetting.s3_backup_bucket.present?
|
||||
require 'fog'
|
||||
@fog = Fog::Storage.new(s3_options)
|
||||
end
|
||||
|
||||
def fog_directory
|
||||
return @fog_directory if @fog_directory
|
||||
return unless fog
|
||||
@fog_directory ||= fog.directories.get(SiteSetting.s3_backup_bucket)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -19,40 +19,45 @@ class OptimizedImage < ActiveRecord::Base
|
||||
unless thumbnail
|
||||
external_copy = Discourse.store.download(upload) if Discourse.store.external?
|
||||
original_path = if Discourse.store.external?
|
||||
external_copy.path
|
||||
external_copy.try(:path)
|
||||
else
|
||||
Discourse.store.path_for(upload)
|
||||
end
|
||||
|
||||
# create a temp file with the same extension as the original
|
||||
extension = File.extname(original_path)
|
||||
temp_file = Tempfile.new(["discourse-thumbnail", extension])
|
||||
temp_path = temp_file.path
|
||||
original_path += "[0]" unless opts[:allow_animation]
|
||||
|
||||
if resize(original_path, temp_path, width, height)
|
||||
thumbnail = OptimizedImage.create!(
|
||||
upload_id: upload.id,
|
||||
sha1: Digest::SHA1.file(temp_path).hexdigest,
|
||||
extension: File.extname(temp_path),
|
||||
width: width,
|
||||
height: height,
|
||||
url: "",
|
||||
)
|
||||
# store the optimized image and update its url
|
||||
url = Discourse.store.store_optimized_image(temp_file, thumbnail)
|
||||
if url.present?
|
||||
thumbnail.url = url
|
||||
thumbnail.save
|
||||
else
|
||||
Rails.logger.error("Failed to store avatar #{size} for #{upload.url} from #{source}")
|
||||
end
|
||||
if original_path.blank?
|
||||
Rails.logger.error("Could not find file in the store located at url: #{upload.url}")
|
||||
else
|
||||
Rails.logger.error("Failed to create optimized image #{width}x#{height} for #{upload.url}")
|
||||
# create a temp file with the same extension as the original
|
||||
extension = File.extname(original_path)
|
||||
temp_file = Tempfile.new(["discourse-thumbnail", extension])
|
||||
temp_path = temp_file.path
|
||||
original_path += "[0]" unless opts[:allow_animation]
|
||||
|
||||
if resize(original_path, temp_path, width, height)
|
||||
thumbnail = OptimizedImage.create!(
|
||||
upload_id: upload.id,
|
||||
sha1: Digest::SHA1.file(temp_path).hexdigest,
|
||||
extension: File.extname(temp_path),
|
||||
width: width,
|
||||
height: height,
|
||||
url: "",
|
||||
)
|
||||
# store the optimized image and update its url
|
||||
url = Discourse.store.store_optimized_image(temp_file, thumbnail)
|
||||
if url.present?
|
||||
thumbnail.url = url
|
||||
thumbnail.save
|
||||
else
|
||||
Rails.logger.error("Failed to store avatar #{size} for #{upload.url} from #{source}")
|
||||
end
|
||||
else
|
||||
Rails.logger.error("Failed to create optimized image #{width}x#{height} for #{upload.url}")
|
||||
end
|
||||
|
||||
# close && remove temp file
|
||||
temp_file.close!
|
||||
end
|
||||
|
||||
# close && remove temp file
|
||||
temp_file.close!
|
||||
# make sure we remove the cached copy from external stores
|
||||
external_copy.close! if Discourse.store.external?
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user