map7
map7

Reputation: 5126

capistrano on_rollback not being called

I'm using capistrano v2 for a Rails 3.2 I have a bundler task in my deploy.rb like so;

# Bundler tasks
namespace :bundler do
  desc "Create a symlink"
  task :create_symlink, :roles => :app do
    shared_dir = File.join(shared_path, 'bundle')
    release_dir = File.join(release_path, '.bundle')
    run("mkdir -p #{shared_dir} && ln -s #{shared_dir} #{release_dir}")
  end

  desc "Install required gems"
  task :install, :roles => :app do
    puts "New Release"
    run "cd #{release_path} && #{bundle_path} install"

    on_rollback do
      if previous_release
        puts "Rollback"
        run "cd #{previous_release} && #{bundle_path} install"
      else
        logger.important "no previous release to rollback to, rollback of bundler:install skipped"
      end
    end
  end

  desc "Run bundler on new release"
  task :bundle_new_release, :roles => :db do
    bundler.create_symlink
    bundler.install
  end
end

after "deploy:update_code", "bundler:bundle_new_release"
after "deploy:rollback:revision", "bundler:install"

When I run cap deploy:rollback it doesn't run the the on_rollback code it tries to run the cd {release_path}.

I got this example from http://kazjote.eu/2010/08/04/bundler-and-capistrano-the-right-way.

Upvotes: 1

Views: 305

Answers (1)

ambled
ambled

Reputation: 11

Since you didn't give any logs, I can't say for sure if deploy:rollback is deploying the previous version as it should, however you're confusing deploy:rollback (a task), with on_rollback (a hook).

on_rollback would be called only if the task :install failed. However, I also believe you need to define a transaction for the on_rollback hook to actually fire (and possibly have to make the on_rollback definition before your 'run "cd...')

deploy:rollback should run your deploy tasks with the previous successful release.

I found a simpler example here:

http://pedz-bits.blogspot.com/2012/09/capistrano-errors-ensure-and-onrollback.html

namespace :fun do
  desc "Sample showing rescue, ensure, and on_rollback inside a transaction"
  task :stuff, :roles => :app do
    transaction do
        on_rollback { logger.debug "my rollback" } 
      begin
        logger.debug "main"
        # Either run or run_locally will work the same
        # run_locally "false"
        run "false"
      rescue => e
        logger.debug "rescue #{e.class}"
        raise e
      ensure
        logger.debug "ensure"
      end
    end
  end
end

Command output:

cap fun:stuff
  * executingD `fun:stuff'
 ** transaction: start
  * main
  * executingB "false"
    servers: ["condor.austin.ibm.com"]
    [condor.austin.ibm.com] executingA command
    command finished in 771ms
  * rescue Capistrano::CommandError
  * ensure
*** [fun:stuff] rolling back
  * my rollback
failed: "bash -l -c 'false'" on condor.austin.ibm.com

Notes

  1. on_rollback executes only if the error happens while a transaction is active.
  2. on_rollback must also be defined within the transaction.
  3. raise e to make sure task exits with an error or higher level process will assume it completed successfully.
  4. ensure works as you expect.

Upvotes: 1

Related Questions