Skip to content

Commit

Permalink
FEATURE: Allow pausing of restore before DB migration and uploads are…
Browse files Browse the repository at this point in the history
… restored (discourse#30269)

This can be helpful if you need to fix problems in the DB before the DB gets migrated as well as before uploads are restored.
  • Loading branch information
gschlager authored Dec 16, 2024
1 parent 04ba5ba commit 6b3e282
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
13 changes: 12 additions & 1 deletion lib/backup_restore/database_restorer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ def initialize(logger, current_db)
@current_db = current_db
end

def restore(db_dump_path)
def restore(db_dump_path, interactive = false)
BackupRestore.move_tables_between_schemas(MAIN_SCHEMA, BACKUP_SCHEMA)

@db_dump_path = db_dump_path
@db_was_changed = true

create_missing_discourse_functions
restore_dump
pause_before_migration if interactive
migrate_database
reconnect_database

Expand Down Expand Up @@ -136,6 +137,16 @@ def self.psql_command
].compact.join(" ")
end

def pause_before_migration
puts ""
puts "Attention! Pausing restore before migrating database.".red.bold
puts "You can work on the restored database in a separate Rails console."
puts ""
puts "Press any key to continue with the restore.".bold
puts ""
STDIN.getch
end

def migrate_database
log "Migrating the database..."

Expand Down
30 changes: 27 additions & 3 deletions lib/backup_restore/restorer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "colored2"

module BackupRestore
RestoreDisabledError = Class.new(RuntimeError)
FilenameMissingError = Class.new(RuntimeError)
Expand All @@ -9,12 +11,20 @@ class Restorer

attr_reader :success

def initialize(user_id:, filename:, factory:, disable_emails: true, location: nil)
def initialize(
user_id:,
filename:,
factory:,
disable_emails: true,
location: nil,
interactive: false
)
@user_id = user_id
@filename = filename
@factory = factory
@logger = factory.logger
@disable_emails = disable_emails
@interactive = interactive

ensure_restore_is_enabled
ensure_we_have_a_user
Expand Down Expand Up @@ -48,7 +58,7 @@ def run
@system.flush_redis
@system.clear_sidekiq_queues

@database_restorer.restore(db_dump_path)
@database_restorer.restore(db_dump_path, @interactive)

reload_site_settings

Expand All @@ -58,7 +68,7 @@ def run
clear_stats
reload_translations

@uploads_restorer.restore(@tmp_directory)
restore_uploads

clear_emoji_cache
clear_theme_cache
Expand Down Expand Up @@ -143,6 +153,20 @@ def reload_translations
TranslationOverride.reload_all_overrides!
end

def restore_uploads
if @interactive
puts ""
puts "Attention! Pausing restore before uploads.".red.bold
puts "You can work on the restored database in a separate Rails console."
puts ""
puts "Press any key to continue with the restore.".bold
puts ""
STDIN.getch
end

@uploads_restorer.restore(@tmp_directory)
end

def notify_user
return if @success && @user_id == Discourse::SYSTEM_USER_ID

Expand Down
10 changes: 9 additions & 1 deletion script/discourse
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,14 @@ class DiscourseCLI < Thor
end

desc "restore", "Restore a Discourse backup"
option :disable_emails, type: :boolean, default: true
option :disable_emails,
type: :boolean,
default: true,
desc: "Disable outgoing emails for non-staff users after restore"
option :pause,
type: :boolean,
default: false,
desc: "Pause before migrating database and restoring uploads"
option :location, type: :string, enum: %w[local s3], desc: "Override the backup location"
def restore(filename = nil)
load_rails
Expand All @@ -179,6 +186,7 @@ class DiscourseCLI < Thor
disable_emails: options[:disable_emails],
location: options[:location],
factory: BackupRestore::Factory.new(user_id: Discourse.system_user.id),
interactive: options[:pause],
)
restorer.run
puts "Restore done."
Expand Down

0 comments on commit 6b3e282

Please sign in to comment.