Skip to content

Instantly share code, notes, and snippets.

@pbonnell
Last active August 29, 2015 14:06
Show Gist options
  • Save pbonnell/60ee36eb7f1715dbb798 to your computer and use it in GitHub Desktop.
Save pbonnell/60ee36eb7f1715dbb798 to your computer and use it in GitHub Desktop.
Sync data between heroku apps
#!/usr/bin/env ruby
require 'optparse'
require 'pty'
#TODO: PTY pushes messages but not the nice progress provided by `heroku pgbackups`
# Pushes messaging from a shell command to stdout.
# So that child processes can report to the script output
# @param cmd [string] the external process to run
#
# @return nil (prints to stdout)
def command_to_stdout(cmd)
begin
PTY.spawn( cmd ) do |stdin, stdout, pid|
begin
# Do stuff with the output here. Just printing to show it works
stdin.each { |line| print line }
rescue Errno::EIO
# "Errno:EIO error, but this probably just means that the process has finished giving output"
puts 'exited...'
end
end
rescue PTY::ChildExited
puts "--"
end
end
options = {}
op = OptionParser.new do |opts|
opts.banner = "Truncates and updates a non-production server with production data.\n ex:\n production-data-sync -s heroku-production -d heroku-stage \n-h for help"
opts.on('-s', '--source HEROKU_PRODUCTION', 'Heroku production') { |v| options[:source] = v }
opts.on('-d', '--destination HEROKU_TARGET', 'Heroku target application (DESTROYS ALL DATA).') { |v| options[:destination] = v }
opts.on('-b', '--backup', 'Capture a pg_backup from source first.') { |v| options[:backup] = true }
opts.on('-m', '--maintenance', 'When capturing the backup, put production in maintenance mode first.') { |v| options[:production_maintenance] = true }
opts.on('-h', '--help', 'HELP') {
puts opts
puts '==> -s, -d are required'
puts "Truncates and updates a non-production server with production data."
puts "ex:"
puts "production-data-sync -s heroku-production -d heroku-stage"
}
end
op.parse!
if options[:source].nil? || options[:destination].nil?
puts op.banner
else
if options[:backup] == true
maintenance_on = "heroku maintenance:on -a#{options[:source]}"
get_backup = "heroku pgbackups:capture --expire -a#{options[:source]}"
maintenance_off = "heroku maintenance:off -a#{options[:source]}"
command_to_stdout( maintenance_on ) if options[:production_maintenance] = true
command_to_stdout( get_backup )
command_to_stdout( maintenance_off ) if options[:production_maintenance] = true
end
maintenance_on = "heroku maintenance:on -a#{options[:destination]}"
truncate = "heroku pg:reset DATABASE -a #{options[:destination]} --confirm #{options[:destination]}"
restore = "heroku pgbackups:restore DATABASE `heroku pgbackups:url -a #{options[:source]}` -a #{options[:destination]} --confirm #{options[:destination]}"
migrate = "heroku run rake db:migrate -a#{options[:destination]}"
maintenance_off = "heroku maintenance:off -a#{options[:destination]}"
[maintenance_on, truncate, restore, migrate, maintenance_off].each do |cmd|
command_to_stdout(cmd)
end
end
@pbonnell
Copy link
Author

mv ~/Downloads/production-data-sync.rb /usr/local/bin/production-data-sync
chmod +x /usr/local/bin/production-data-sync

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment