DEV: Split max decompressed setting for themes and backups (#8179)

This commit is contained in:
Roman Rizzi 2019-10-11 14:38:10 -03:00 committed by GitHub
parent f63db1c4c8
commit 01bc465db8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 47 additions and 14 deletions

View File

@ -1201,9 +1201,12 @@ files:
default: 5
min: 0
max: 20
decompressed_file_max_size_mb:
decompressed_theme_max_file_size_mb:
default: 1000
hidden: true
decompressed_backup_max_file_size_mb:
default: 100000
hidden: true
trust:
default_trust_level:

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class MigrateDecompressedFileMaxSizeMb < ActiveRecord::Migration[6.0]
def up
current_value = DB.query_single("SELECT value FROM site_settings WHERE name ='decompressed_file_max_size_mb' ").first
if current_value && current_value != '1000'
DB.exec <<~SQL
INSERT INTO site_settings (name, data_type, value, created_at, updated_at)
VALUES
('decompressed_theme_max_file_size_mb', 3, #{current_value}, current_timestamp, current_timestamp),
('decompressed_backup_max_file_size_mb', 3, #{current_value}, current_timestamp, current_timestamp)
SQL
end
end
def down
end
end

View File

@ -92,6 +92,9 @@ module BackupRestore
extract_uploads
after_restore_hook
rescue Compression::Strategy::ExtractFailed
log "The uncompressed file is too big. Consider increasing the decompressed_theme_max_file_size_mb hidden setting."
rollback
rescue SystemExit
log "Restore process was cancelled!"
rollback
@ -138,7 +141,7 @@ module BackupRestore
pipeline = Compression::Pipeline.new([Compression::Tar.new, Compression::Gzip.new])
unzipped_path = pipeline.decompress(@tmp_directory, @archive_filename)
unzipped_path = pipeline.decompress(@tmp_directory, @archive_filename, available_size)
pipeline.strip_directory(unzipped_path, @tmp_directory)
end
@ -170,11 +173,15 @@ module BackupRestore
log "Extracting dump file..."
Compression::Gzip.new.decompress(@tmp_directory, @dump_filename)
Compression::Gzip.new.decompress(@tmp_directory, @dump_filename, available_size)
end
protected
def available_size
SiteSetting.decompressed_backup_max_file_size_mb
end
def ensure_restore_is_enabled
raise BackupRestore::RestoreDisabledError unless Rails.env.development? || SiteSetting.allow_restore?
end

View File

@ -20,10 +20,10 @@ module Compression
end
end
def decompress(dest_path, compressed_file_path, allow_non_root_folder: false)
def decompress(dest_path, compressed_file_path, max_size, allow_non_root_folder: false)
@strategies.reverse.reduce(compressed_file_path) do |to_decompress, strategy|
last_extension = strategy.extension
strategy.decompress(dest_path, to_decompress, allow_non_root_folder: allow_non_root_folder)
strategy.decompress(dest_path, to_decompress, max_size, allow_non_root_folder: allow_non_root_folder)
to_decompress.gsub(last_extension, '')
end
end

View File

@ -9,11 +9,11 @@ module Compression
file_name.include?(extension)
end
def decompress(dest_path, compressed_file_path, allow_non_root_folder: false)
def decompress(dest_path, compressed_file_path, max_size, allow_non_root_folder: false)
sanitized_compressed_file_path = sanitize_path(compressed_file_path)
get_compressed_file_stream(sanitized_compressed_file_path) do |compressed_file|
available_size = calculate_available_size
available_size = calculate_available_size(max_size)
entries_of(compressed_file).each do |entry|
entry_path = build_entry_path(
@ -59,8 +59,8 @@ module Compression
end
end
def calculate_available_size
1024**2 * (SiteSetting.decompressed_file_max_size_mb / 1.049) # Mb to Mib
def calculate_available_size(max_size)
1024**2 * (max_size / 1.049) # Mb to Mib
end
def entries_of(compressed_file)

View File

@ -18,8 +18,9 @@ class ThemeStore::ZipImporter
FileUtils.mkdir(@temp_folder)
Dir.chdir(@temp_folder) do
available_size = SiteSetting.decompressed_theme_max_file_size_mb
Compression::Engine.engine_for(@original_filename).tap do |engine|
engine.decompress(@temp_folder, @filename)
engine.decompress(@temp_folder, @filename, available_size)
engine.strip_directory(@temp_folder, @temp_folder, relative: true)
end
end

View File

@ -63,7 +63,8 @@ describe ThemeStore::ZipExporter do
file = 'discourse-header-icons.zip'
dest = 'discourse-header-icons'
Dir.chdir(dir) do
Compression::Zip.new.decompress(dir, file, allow_non_root_folder: true)
available_size = SiteSetting.decompressed_theme_max_file_size_mb
Compression::Zip.new.decompress(dir, file, available_size, allow_non_root_folder: true)
`rm #{file}`
folders = Dir.glob("**/*").reject { |f| File.file?(f) }

View File

@ -3,6 +3,8 @@
require 'rails_helper'
describe Compression::Engine do
let(:available_size) { SiteSetting.decompressed_theme_max_file_size_mb }
before do
@temp_folder = "#{Pathname.new(Dir.tmpdir).realpath}/#{SecureRandom.hex}"
@folder_name = 'test'
@ -36,7 +38,7 @@ describe Compression::Engine do
it 'decompress the folder and inspect files correctly' do
engine = described_class.engine_for(@compressed_path)
engine.decompress(@temp_folder, "#{@temp_folder}/#{@folder_name}.zip")
engine.decompress(@temp_folder, "#{@temp_folder}/#{@folder_name}.zip", available_size)
expect(read_file("test/hello.txt")).to eq("hello world")
expect(read_file("test/a/inner")).to eq("hello world inner")
@ -49,7 +51,7 @@ describe Compression::Engine do
it 'decompress the folder and inspect files correctly' do
engine = described_class.engine_for(@compressed_path)
engine.decompress(@temp_folder, "#{@temp_folder}/#{@folder_name}.tar.gz")
engine.decompress(@temp_folder, "#{@temp_folder}/#{@folder_name}.tar.gz", available_size)
expect(read_file("test/hello.txt")).to eq("hello world")
expect(read_file("test/a/inner")).to eq("hello world inner")
@ -62,7 +64,7 @@ describe Compression::Engine do
it 'decompress the folder and inspect files correctly' do
engine = described_class.engine_for(@compressed_path)
engine.decompress(@temp_folder, "#{@temp_folder}/#{@folder_name}.tar")
engine.decompress(@temp_folder, "#{@temp_folder}/#{@folder_name}.tar", available_size)
expect(read_file("test/hello.txt")).to eq("hello world")
expect(read_file("test/a/inner")).to eq("hello world inner")