# rubocop:disable all require 'yaml' require 'json' require 'shellwords'
namespace :db do
task :load_from_remote do |t, _| RemoteDbLoader.new.call end
end
class RemoteDbLoader
def call
env = 'staging'
env = ENV['SERVER'] if ENV['SERVER'].present?
to_be_rsync_folder = ENV['SYNC_FOLDER']
database_yml =
"#{Rails.root}/config/database.yml"
development_db = YAML.load_file(database_yml)[ENV['RAILS_ENV'] || 'development']
username = development_db['username'] || 'root'
password = development_db['password']
database = development_db['database']
host = development_db['host'] || 'localhost'
begin
eval File.read("#{Rails.root}/config/deploy.rb")
rescue LoadError
end
eval File.read("#{Rails.root}/config/deploy/#{env}.rb")
port = @port || 22
## get remote database config.yml
puts "ssh #{@server_user}@#{@server_ip} -p#{port} which ruby"
ruby_cmd = `ssh #{@server_user}@#{@server_ip} -p#{port} which ruby`.strip
if ruby_cmd.blank?
ruby_cmd = "/home/#{@server_user}/.rbenv/shims/ruby"
end
get_db_info_command = %{ssh #{@server_user}@#{@server_ip} -p#{port} \
"#{ruby_cmd} -e \
\\"require 'yaml'; \
puts YAML.load_file('#{@deploy_to}/shared/config/database.yml')['#{env}']\\""}
shared_path = ENV['TEMP_STORED_FOLDER'] || "#{@deploy_to}/shared"
puts get_db_info_command
remote_db_config = eval `#{get_db_info_command}`
remote_db_host = remote_db_config["host"] || 'localhost'
remote_db_name = remote_db_config["database"]
remote_db_username = remote_db_config["username"] || 'root'
remote_db_password = remote_db_config["password"]
## run the real backup
puts 'Running the remote backup...'
mysql_cmd = "mysqldump -u #{remote_db_username} -p'#{remote_db_password}' \
-h #{remote_db_host} #{remote_db_name} > \
#{shared_path}/backup.sql".shellescape
backup_command = %(ssh #{@server_user}@#{@server_ip} -p#{port} #{mysql_cmd})
system(backup_command)
check_gzip_exist_cmd = 'which gzip'
check_gzip_exist_remote_cmd =
%(ssh #{@server_user}@#{@server_ip} -p#{port} #{check_gzip_exist_cmd})
puts 'Checking for remote gzip location...'
gzip_exist = system(check_gzip_exist_remote_cmd) != ''
if gzip_exist
puts 'zipping remote backup file...'
zip_cmd = "gzip -f #{shared_path}/backup.sql"
zip_cmd_remote =
%(ssh #{@server_user}@#{@server_ip} -p#{port} #{zip_cmd})
system(zip_cmd_remote)
end
puts 'Downloading remote backup file...'
bk_extension = gzip_exist ? 'sql.gz' : 'sql'
download_db_dump_command =
%(scp -P#{port} #{@server_user}@#{@server_ip}:#{shared_path}/backup.#{bk_extension} .)
system(download_db_dump_command)
puts 'Deleting remote backup file...'
delete_db_dump_command = %(ssh #{@server_user}@#{@server_ip} -p#{port} \
"rm -rf #{shared_path}/backup.#{bk_extension}")
system(delete_db_dump_command)
if gzip_exist
`gunzip -f backup.sql.gz`
end
if ENV['DOWNLOAD_ONLY']
puts 'backup.sql file is now stored at your Rails root folder!'
`open .`
else
# run db create in case the db does not exist
`bundle exec rake db:create`
if password == nil
import_db_cmd =
%(mysql -u #{username} #{database} -h #{host} < backup.sql)
else
import_db_cmd =
%(mysql -u #{username} -p'#{password}' -h #{host} #{database} < backup.sql)
end
puts 'Importing database into local environment...'
`#{import_db_cmd}`
puts 'Cleaning up database backup...'
`rm backup.sql`
end
if to_be_rsync_folder
puts "Synchorinizing #{to_be_rsync_folder} folder..."
`mkdir -p #{to_be_rsync_folder}`
sync_folder_cmd = %(rsync -r \
#{@server_user}@#{@server_ip}:#{shared_path}/#{to_be_rsync_folder}/ \ #{to_be_rsync_folder})
puts sync_folder_cmd
system(sync_folder_cmd)
end
puts 'DONE!'
end
def method_missing(name, *args, &block)
if name == :fetch && (args[0] == :deploy_user || args[0] == :user)
return @server_user
end
if name == :fetch && args[0] == :application
return @application
end
if name == :fetch && args[0] == :full_app_name
return @full_app_name
end
if name == :fetch && args[0] == :stage
return @stage
end
return self unless %I[server set].include?(name)
@server_ip ||= if name == :server
args[0]
elsif name == :set && args[0] == :domain
args[1]
end
@server_user ||= args[1] if name == :set && args[0] == :user
@stage ||= args[1] if name == :set && args[0] == :stage
@server_user = args[1] if name == :set && args[0] == :deploy_user
@application ||= args[1] if name == :set && args[0] == :application
@full_app_name ||= args[1] if name == :set && args[0] == :full_app_name
@port ||= args[1] if name == :set && args[0] == :port
if name == :set && args[0] == :deploy_to
puts args[1]
@deploy_to ||= args[1]
end
end
end