Skip to content

Instantly share code, notes, and snippets.

@tspacek
Created January 4, 2014 05:37
Show Gist options
  • Save tspacek/8252122 to your computer and use it in GitHub Desktop.
Save tspacek/8252122 to your computer and use it in GitHub Desktop.
Quick and dirty script to upgrade a Heroku Postgres DB according to https://devcenter.heroku.com/articles/heroku-postgres-follower-databases#database-upgrades-and-migrations-with-changeovers Usage: ruby upgrade.rb <app_name> with_worker
@app = ARGV[0]
puts @app
@scale_worker = (ARGV.last == "with_worker")
def prepare
db_info = `heroku pg:info -a #{@app}`
@db_name = db_info.split("\n").first.split(" ")[1]
follower_available = db_info.include? "Fork/Follow: Available"
if not follower_available
puts "Follower not available."
exit
end
follower_command = "heroku addons:add heroku-postgresql:crane --follow #{@db_name} -a #{@app}"
puts "Doing: '#{follower_command}'"
follower_info = `#{follower_command}`
@follower_db = follower_info[/(?<=(Attached as )).*/]
if not @follower_db or @follower_db.empty?
puts "Could not add follower"
exit
else
puts "Added follower at #{@follower_db}"
end
puts "Waiting.."
system "heroku pg:wait -a #{@app}"
puts "Maintenance mode ON"
system "heroku maintenance:on -a #{@app}"
system "heroku scale worker=0 -a #{@app}" if @scale_worker
puts "Check follower is up to date.."
pg_status = `heroku pg:info -a #{@app}`
if not pg_status.include? "Behind By: 0 commits"
puts "Follower hasn't caught up"
exit
end
puts pg_status
end
def promote
@follower_db ||= ARGV[2]
puts "Using follower #{@follower_db}"
system "heroku pg:unfollow #{@follower_db} -a #{@app} --confirm #{@app}"
system "heroku pg:promote #{@follower_db} -a #{@app} --confirm #{@app}"
puts "Maintenance OFF"
system "heroku ps:scale worker=1 -a #{@app}" if @scale_worker
system "heroku maintenance:off -a #{@app}"
if @db_name
puts "Back up and running. Remember to remove the old database with:"
puts "heroku addons:remove #{@db_name.gsub('_URL', '')} -a #{@app}"
else
puts "Back up and running. Remember to remove the old database."
end
end
if ARGV[1] == "prepare"
prepare
elsif ARGV[1] == "promote"
promote
else
prepare
promote
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment