mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: Split max decompressed setting for themes and backups (#8179)
This commit is contained in:
parent
f63db1c4c8
commit
01bc465db8
@ -1201,9 +1201,12 @@ files:
|
|||||||
default: 5
|
default: 5
|
||||||
min: 0
|
min: 0
|
||||||
max: 20
|
max: 20
|
||||||
decompressed_file_max_size_mb:
|
decompressed_theme_max_file_size_mb:
|
||||||
default: 1000
|
default: 1000
|
||||||
hidden: true
|
hidden: true
|
||||||
|
decompressed_backup_max_file_size_mb:
|
||||||
|
default: 100000
|
||||||
|
hidden: true
|
||||||
|
|
||||||
trust:
|
trust:
|
||||||
default_trust_level:
|
default_trust_level:
|
||||||
|
@ -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
|
@ -92,6 +92,9 @@ module BackupRestore
|
|||||||
extract_uploads
|
extract_uploads
|
||||||
|
|
||||||
after_restore_hook
|
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
|
rescue SystemExit
|
||||||
log "Restore process was cancelled!"
|
log "Restore process was cancelled!"
|
||||||
rollback
|
rollback
|
||||||
@ -138,7 +141,7 @@ module BackupRestore
|
|||||||
|
|
||||||
pipeline = Compression::Pipeline.new([Compression::Tar.new, Compression::Gzip.new])
|
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)
|
pipeline.strip_directory(unzipped_path, @tmp_directory)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -170,11 +173,15 @@ module BackupRestore
|
|||||||
|
|
||||||
log "Extracting dump file..."
|
log "Extracting dump file..."
|
||||||
|
|
||||||
Compression::Gzip.new.decompress(@tmp_directory, @dump_filename)
|
Compression::Gzip.new.decompress(@tmp_directory, @dump_filename, available_size)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def available_size
|
||||||
|
SiteSetting.decompressed_backup_max_file_size_mb
|
||||||
|
end
|
||||||
|
|
||||||
def ensure_restore_is_enabled
|
def ensure_restore_is_enabled
|
||||||
raise BackupRestore::RestoreDisabledError unless Rails.env.development? || SiteSetting.allow_restore?
|
raise BackupRestore::RestoreDisabledError unless Rails.env.development? || SiteSetting.allow_restore?
|
||||||
end
|
end
|
||||||
|
@ -20,10 +20,10 @@ module Compression
|
|||||||
end
|
end
|
||||||
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|
|
@strategies.reverse.reduce(compressed_file_path) do |to_decompress, strategy|
|
||||||
last_extension = strategy.extension
|
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, '')
|
to_decompress.gsub(last_extension, '')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -9,11 +9,11 @@ module Compression
|
|||||||
file_name.include?(extension)
|
file_name.include?(extension)
|
||||||
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)
|
||||||
sanitized_compressed_file_path = sanitize_path(compressed_file_path)
|
sanitized_compressed_file_path = sanitize_path(compressed_file_path)
|
||||||
|
|
||||||
get_compressed_file_stream(sanitized_compressed_file_path) do |compressed_file|
|
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|
|
entries_of(compressed_file).each do |entry|
|
||||||
entry_path = build_entry_path(
|
entry_path = build_entry_path(
|
||||||
@ -59,8 +59,8 @@ module Compression
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def calculate_available_size
|
def calculate_available_size(max_size)
|
||||||
1024**2 * (SiteSetting.decompressed_file_max_size_mb / 1.049) # Mb to Mib
|
1024**2 * (max_size / 1.049) # Mb to Mib
|
||||||
end
|
end
|
||||||
|
|
||||||
def entries_of(compressed_file)
|
def entries_of(compressed_file)
|
||||||
|
@ -18,8 +18,9 @@ class ThemeStore::ZipImporter
|
|||||||
FileUtils.mkdir(@temp_folder)
|
FileUtils.mkdir(@temp_folder)
|
||||||
|
|
||||||
Dir.chdir(@temp_folder) do
|
Dir.chdir(@temp_folder) do
|
||||||
|
available_size = SiteSetting.decompressed_theme_max_file_size_mb
|
||||||
Compression::Engine.engine_for(@original_filename).tap do |engine|
|
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)
|
engine.strip_directory(@temp_folder, @temp_folder, relative: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -63,7 +63,8 @@ describe ThemeStore::ZipExporter do
|
|||||||
file = 'discourse-header-icons.zip'
|
file = 'discourse-header-icons.zip'
|
||||||
dest = 'discourse-header-icons'
|
dest = 'discourse-header-icons'
|
||||||
Dir.chdir(dir) do
|
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}`
|
`rm #{file}`
|
||||||
|
|
||||||
folders = Dir.glob("**/*").reject { |f| File.file?(f) }
|
folders = Dir.glob("**/*").reject { |f| File.file?(f) }
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe Compression::Engine do
|
describe Compression::Engine do
|
||||||
|
let(:available_size) { SiteSetting.decompressed_theme_max_file_size_mb }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@temp_folder = "#{Pathname.new(Dir.tmpdir).realpath}/#{SecureRandom.hex}"
|
@temp_folder = "#{Pathname.new(Dir.tmpdir).realpath}/#{SecureRandom.hex}"
|
||||||
@folder_name = 'test'
|
@folder_name = 'test'
|
||||||
@ -36,7 +38,7 @@ describe Compression::Engine do
|
|||||||
it 'decompress the folder and inspect files correctly' do
|
it 'decompress the folder and inspect files correctly' do
|
||||||
engine = described_class.engine_for(@compressed_path)
|
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/hello.txt")).to eq("hello world")
|
||||||
expect(read_file("test/a/inner")).to eq("hello world inner")
|
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
|
it 'decompress the folder and inspect files correctly' do
|
||||||
engine = described_class.engine_for(@compressed_path)
|
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/hello.txt")).to eq("hello world")
|
||||||
expect(read_file("test/a/inner")).to eq("hello world inner")
|
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
|
it 'decompress the folder and inspect files correctly' do
|
||||||
engine = described_class.engine_for(@compressed_path)
|
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/hello.txt")).to eq("hello world")
|
||||||
expect(read_file("test/a/inner")).to eq("hello world inner")
|
expect(read_file("test/a/inner")).to eq("hello world inner")
|
||||||
|
Loading…
Reference in New Issue
Block a user