Skip to content

Instantly share code, notes, and snippets.

@thabotitus
Created February 20, 2023 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thabotitus/dceb0d61343823874456fb78f6492378 to your computer and use it in GitHub Desktop.
Save thabotitus/dceb0d61343823874456fb78f6492378 to your computer and use it in GitHub Desktop.
Restore local DB with backup from S3
# frozen_string_literal: true
require 'rubygems/package'
require 'zlib'
namespace :maintenance do
desc 'Restore local with remote backup'
task restore_local: :environment do
lambda do
return unless Rails.env.development?
logger = Logger.new(STDOUT)
db_config = Rails.configuration.database_configuration[Rails.env]
Bundler.with_unbundled_env do
logger.info "=================================================="
logger.info "Getting DB from S3"
logger.info "=================================================="
`unset NODE_OPTIONS`
logger.info "[1/11] Downloading latest backup onto disk"
downloaded_file_path = download_from_s3
tmp_dir = Rails.root.join('tmp','backups','latest').to_s
logger.info "[2/11] Unzipping archive"
Dir.mkdir(tmp_dir) unless File.exists?(tmp_dir)
unzip_file(downloaded_file_path, tmp_dir)
return unless downloaded_file_path.present?
logger.info "[3/11] Set env to development"
`bin/rails db:environment:set RAILS_ENV=development`
logger.info "[4/11] Drop databases"
Rake::Task['db:drop'].invoke
logger.info "[5/11] Re-create databases"
Rake::Task['db:create'].invoke
logger.info "[6/11] Mounting backup on local database"
`pg_restore --clean --verbose --no-acl --no-owner -h localhost -d #{db_config["database"]} -F d #{tmp_dir}`
logger.info "[7/11] Cleaning up downloads"
`rm #{downloaded_file_path}`
`rm -rf #{tmp_dir}`
logger.info "[8/11] DB Migrate"
`bin/rails db:migrate`
Rake::Task['dev:reset_passwords'].invoke
logger.info "[9/11] Reset Passwords"
Rake::Task['features:seed'].invoke
Flipper.features.each(&:enable)
logger.info "[10/11] Remove Card Authorizations"
Wallet::CardAuthorization.destroy_all
BankAccount.destroy_all
logger.info "[11/11] Masking Data"
Rake::Task['dev:mask_data'].invoke
logger.info "DONE 🔥"
end
end.call
end
private
def download_from_s3
bucket = Aws::S3::Bucket.new("ubuntu-rewards-production-database-backups")
items = []
bucket.objects.each {|o| items << o }
latest = items.sort_by {|c| c.last_modified }.last
file_path = Rails.root.join('tmp', 'backups', 'latest.tar.gz')
return file_path if File.exists?(file_path)
return file_path.to_s if latest.download_file(file_path, { mode: 'auto' })
false
end
def unzip_file (file, destination)
tar_long_link = '././@LongLink'
tar_gz_archive = file
Gem::Package::TarReader.new( Zlib::GzipReader.open tar_gz_archive ) do |tar|
dest = nil
tar.each do |entry|
if entry.full_name == tar_long_link
dest = File.join destination, entry.read.strip
next
end
dest ||= File.join destination, entry.full_name
if entry.directory?
File.delete dest if File.file? dest
FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
elsif entry.file?
FileUtils.rm_rf dest if File.directory? dest
File.open dest, "wb" do |f|
f.print entry.read
end
FileUtils.chmod entry.header.mode, dest, :verbose => false
elsif entry.header.typeflag == '2' #Symlink!
File.symlink entry.header.linkname, dest
end
dest = nil
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment