jqr/heroku_san

pgbackups and other local commands

jkamenik opened this issue · 2 comments

I have a rails app and before I do a migration I do a manual backup just incase I have to rollback. I can't use run because it needs to execute locally, but sh_heroku fails:

heroku-toolbelt/2.39.2 (x86_64-darwin10.8.0) ruby/1.9.3
help pgbackups --app waterfalldev
 !    `help pgbackups` is not a heroku command.
 !    See `heroku help` for a list of available commands.
rake aborted!
Command failed with status (1): [heroku help pgbackups --app waterfalldev]

The current sh_heroku can't deal with executing local commands. I think it has to do with how system 'command args' is processed differently then system 'command', args.

There has to be a better then this, but here is what I came up with.

class HerokuSan::Stage
  public :sh_heroku
  def sh_heroku_local(*command)
    @debug = true
    preflight_check_for_cli
    cmd = (['heroku'] + command + ['--app', app]).compact
    show_command = cmd.join(' ')
    $stderr.puts show_command if @debug
    ok = system show_command
    status = $?
    ok or fail "Command failed with status (#{status.exitstatus}): [heroku #{show_command}]"
  end
end

Results of using sh_heroku_local

heroku-toolbelt/2.39.2 (x86_64-darwin10.8.0) ruby/1.9.3
heroku help pgbackups --app waterfalldev
Usage: heroku pgbackups

 list captured backups

Additional commands, type "heroku help COMMAND" for more details:

  pgbackups:capture [DATABASE]                           #  capture a backup from a database id
  pgbackups:destroy BACKUP_ID                            #  destroys a backup
  pgbackups:restore [<DATABASE> [BACKUP_ID|BACKUP_URL]]  #  restore a backup to a database
  pgbackups:url [BACKUP_ID]                              #  get a temporary URL for a backup

I was able to get this working by doing the following:

stage.send(:sh_heroku, 'pgbackups:capture', '--expire')

Notice you need to pass the command args as separate arguments to the method rather than encoding the command and args in a single string. I'd still love a more out of the box solution for this though :)

If anybody is still looking at this, I used this:

def backup_database
  puts "Create pg:backup for #{@stage.name}"
  @stage.heroku.sh(@stage.app, "pg:backups", "capture")
end