lib/gdk/command/reset_data.rb (96 lines of code) (raw):
# frozen_string_literal: true
require 'fileutils'
module GDK
module Command
# Handles `gdk reset-data` command execution
class ResetData < BaseCommand
def run(_ = [])
return false unless continue?
return false unless stop_and_backup!
reset_data!
end
private
def stop_and_backup!
Runit.stop(quiet: true)
return true if backup_data
GDK::Output.error('Failed to backup data.')
display_help_message
false
end
def reset_data!
result = GDK.make('gitlab-topology-service-setup', 'ensure-databases-setup', 'reconfigure')
if result.success?
GDK::Output.notice('Successfully reset data!')
GDK::Command::Start.new.run
else
GDK::Output.error('Failed to reset data.', result.stderr_str)
display_help_message
false
end
end
def continue?
GDK::Output.warn("We're about to remove _all_ (GitLab and praefect) PostgreSQL data, Rails uploads and git repository data.")
GDK::Output.warn("Backups will be made in '#{GDK.root.join('.backups')}', just in case!")
return true if ENV.fetch('GDK_RESET_DATA_CONFIRM', 'false') == 'true' || !GDK::Output.interactive?
GDK::Output.prompt('Are you sure? [y/N]').match?(/\Ay(?:es)*\z/i)
end
def backup_data
move_postgres_data && move_redis_dump_rdb && move_rails_uploads && move_git_repository_data
end
def current_timestamp
@current_timestamp ||= Time.now.strftime('%Y-%m-%d_%H.%M.%S')
end
def create_directory(directory)
directory = gdk_root_pathed(directory)
Dir.mkdir(directory) unless directory.exist?
true
rescue Errno::ENOENT => e
GDK::Output.error("Failed to create directory '#{directory}' - #{e}", e)
false
end
def backup_path(message, *path)
path_to_backup = gdk_backup_pathed_timestamped(*path)
path = gdk_root_pathed(*path)
return true unless path.exist?
GDK::Output.notice("Moving #{message} from '#{path}' to '#{path_to_backup}/'")
# Ensure the base path exists
FileUtils.mkdir_p(path_to_backup.dirname)
FileUtils.mv(path, path_to_backup)
true
rescue SystemCallError => e
GDK::Output.error("Failed to rename path '#{path}' to '#{path_to_backup}/' - #{e}", e)
false
end
def gdk_backup_pathed_timestamped(*path)
path = path.flatten
path[-1] = "#{path[-1]}.#{current_timestamp}"
GDK.root.join('.backups', *path)
end
def gdk_root_pathed(*path)
GDK.root.join(*path.flatten)
end
def move_postgres_data
backup_path('PostgreSQL data', %w[postgresql data])
end
def move_redis_dump_rdb
backup_path('redis dump.rdb', %w[redis dump.rdb])
end
def move_rails_uploads
backup_path('Rails uploads', %w[gitlab public uploads])
end
def move_git_repository_data
backup_path('git repository data', 'repositories') &&
restore_repository_data_dir &&
backup_path('more git repository data', 'repository_storages')
end
def restore_repository_data_dir
sh = Shellout.new('git restore repositories', chdir: GDK.root)
sh.try_run
sh.success?
end
def touch_file(file)
FileUtils.touch(file)
true
rescue SystemCallError
false
end
end
end
end