How to run Capistrano task on failed deploy - ruby

Using Capistrano I'd like to run a cleanup/teardown task on failed deploy, such as when a shell command fails.
I couldn't find anything after a fairly extensive search.
Can anyone help? Thanks

Take a look on Capistrano source code:
https://github.com/capistrano/capistrano/blob/master/lib/capistrano/recipes/deploy.rb
https://github.com/capistrano/capistrano/blob/master/lib/capistrano/configuration/execution.rb
It depends on how your task is. Basically, there are some snippets for rolling back thing:
task :my_task do
on_rollback { "rm -rf data_dir" }
exec "mkdir data_dir"
exec "some commands for preparaing data in data_dir"
end
after "deploy:create_symlink", :my_task
In above case, my_task should be run in a transaction. And yes, it's already in transaction because deploy:create_symlink is a subtask of deploy which creates a transaction.
If you want to run my_task standalone (not a subtask of cap deploy process). You should create another task like below, and run cap my_task_standalone from command line.
task :my_task_standalone do
transaction do
my_task
end
end

Related

Running Typesafe Activator from inside Chef cookbook does not work

I have a simple cookbook that uses bash to execute Typesafe's activator, but running "activator stage" action never finishes.
bash "Prepare App" do
user "#{username}"
group "#{username}"
cwd "/home/#{username}/my-app"
code <<-EOH
activator stage
EOH
end
The recipe above will timeout and never do what is supposed to.
If I run the same command:
activator stage
from the command line then it works fine. Can someone help me figure this out?

Have Heroku App Restart it self from Heroku

So, if I run the command heroku ps:restart event_machine.1 --app app-name I get what I want. However, I'm trying to automate our travis-ci deploy process. What needs to happen is the following:
We have a successful test run.
Next, we deploy the code
If we deploy the code successfully, we need to execute a few rake tasks that tell an external service to rebuild it self.
Once this is fired off, we need to restart the heroku app. In travis, ideally, this would be executed on the heroku machine via a deploy run command. This would be done in much the same way that we run bundle exec db:migrate.
Does anyone have any thoughts on how we we can restart a particular dyno(s) via a command that can be ran via heroku run something as that is what travis is executing in the deploy run.
So, to answer this we had a procfile that is executing a rake command to spin up event machine. We've modified this at the proc file level to first tell the external service to rebuild it self, before starting the event machine. This takes travis completely out of the deployment loop, which is better because it allows Heroku and Travis to each do what they should be responsible for.

How to execute a rake task using mina?

I want to run a rake task (migrate) contained in my Rakefile in my Sinatra app. I am using Mina to deploy. rake migrate works great if I run it on the server or on my development, but I cannot get Mina to execute the task.
My current deploy looks like this within config/deploy.rb
task :deploy => :environment do
deploy do
# Put things that will set up an empty directory into a fully set-up
# instance of your project.
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
to :launch do
queue "sudo /opt/nginx/sbin/nginx -s reload"
end
end
end
I tried both queue "rake migrate" and queue "#{rake} migrate" within the deploy block and within the launch block but it always complains bash: command not found
in Mina, use ssh to execute rake not quite a smart move.
mina 'rake[rake_taks:taks_whatever_you_write]' on= environment
that is better.
Mina uses ssh to run remote commands. That means that the commands run in a different environment as when you log in. This is causing problems with rvm and rbenv as they are not initialised properly. Luckily, mina has rvm support, you just have to set it up:
require 'mina/rvm'
task :environment do
invoke :'rvm:use[ruby-1.9.3-p125#gemset_name]'
end
task :deploy => :environment do
...
end
You can do a similar thing for rbenv (documentation)

Heroku scheduler Resque

I have a ruby on rails app (1.9.2 and 3.2) running on Heroku with Redis/Resque that requires a rake task be enqueued at regular intervals. Right now I am running 'heroku run rake update_listings' from my local machine once or twice a day....I would like to automate this. I've tried the whenever gem, but the task would not start up in the background. Heroku scheduler seems like the appropriate solution, but I am confused by the scheduler.rb file. I have:
desc "This task is called by the Heroku scheduler add-on"
task :hourly_feed => :environment do
Rake::Task[update_listings].execute
end
When I ran the :hourly_feed task from the Heroku Scheduler console and checked heroku logs, I saw several web dynos get spun up by hirefireapp, but the update_listings rake task was never invoked.
Update: I gave up on resque_scheduler. I am too green to make this work, so trying to use crontab and a sript file. Here is my update.sh script file:
Rake::Task["update_listings"].execute
I set cron using crontab-e and I have it executed every 5 minutes, but I get an error in mail logs:
Projects/livebytransit/update.sh: line 1: Rake::Task[update_listings].execute: command not found
It appears it is finding my update.sh script file and reading it, but it is not executing the code. I noticed the log entry dropped the quotes, so I also tried using single quotes in the shell script file, no change. I also tried changing the update.sh to this:
heroku run rake update_listings
error came back heroku: command not found
Personally, I used resque_scheduler, which will add jobs to the resque / redis queue using cron.
resque_schedule.yml
count_delayed_jobs_job:
cron: "0 */1 * * *"
class: Support::CountDelayedJobsResque
queue: CDJ
args:
description: "count_delayed_jobs_job, every 1hr"
alternatively, you could just chuck Rake::Task["update_listings"].execute in a shell script and use crontab to trigger the job.
It turns out the Heroku Scheduler works perfectly...I simply forgot the quotes around "updated listings".

Rails + Heroku :: rake task inside cron task

Questions
1) When running cron tasks at Heroku, does Heroku have a time limit that cron tasks should last only X minutes or can the cron task run for whatever time it needs to complete processing?
2) To optimize my application, I want to move all my processing to batch mode. So I have lots of update queries. Basically that one Heroku cron file is getting messy. What can I do to clean up the code? Should I create multiple rake tasks and invoke the task tasks from the cron file?
2.1) If you agree with that then how do I invoke rake tasks from cron task? Let's say there are 3 independent rake tasks rake accounts:billing, rake accounts:collections, rake accounts:cleanup. How do I call them in cron file?
There aren't any time limits that I know of.
Using multiple tasks instead of one big cron task is a good idea. Not only is it easier to debug and maintain when they're separate but you can also easily run them individually when needed. And well factored code is a just a good idea all by itself.
Executing a task from another task is as simple as Rake::Task[task].execute. You'd have something like this:
desc 'Heroku cron job'
task :cron => :environment do
%w{accounts:billing accounts:collections accounts:cleanup}.each do |task|
Rake::Task[task].execute
end
end

Resources