I want to run a function before any Capistrano v2.X task is invoked in the deploy namespace.
I have the following which works for a specific task, but how do I hook for all tasks in the namespace, not just a particular task?
before "deploy:justin" do
puts "in before hook"
my_funnction_here
end
namespace :deploy do
task :justin do
puts "in task justin"
end
end
There are some built in points in Capistrano's deployment flow that you can hook into.
For example you can do:
before 'deploy:starting', :some_task do
# Your code here
end
See http://capistranorb.com/documentation/getting-started/flow/ for the list.
I think with that and a little reshuffling of your current code you can make it work. Hope that helps.
Related
I use Capistrano for deploy. My Capistrano tasks are almost quoted from many blogs. I often find following structure.
namespace :deploy do
desc 'Say something before Deploy'
task :initial do
on roles(:app) do
before 'deploy:hoge', 'deploy:bazz'
invoke 'deploy'
end
end
task :hoge do
on roles(:app) do
puts "'hello, world'"
end
end
task :bazz do
on roles(:app) do
puts "'goodnight, world'"
end
end
end
What does before 'deploy:hoge', 'deploy:bazz' do in task statement? It doesn't display any messages. I think before statement must be outside of task statement.
In Capistrano 3.x at least, there is no such thing as a built-in deploy:initial task. Declaring a task with that name does not do anything special.
I think before statement must be outside of task statement.
You are exactly right. Any before and after declarations should be done at the top level and never within a task block.
As it stands, the example that you gave does nothing. If you want to run a certain task before deploy begins, you would hook into the deploy:starting task, like this:
before "deploy:starting", "deploy:hoge"
Furthermore, there is nothing special about the deploy namespace. I recommend declaring your own custom tasks in a different namespace, to keep them visually separated. Then you can easily distinguish between a built-in Capistrano task and your custom ones.
So I would rewrite the example like this:
namespace :myapp do
task :hoge do
on roles(:app) do
puts "'hello, world'"
end
end
task :bazz do
on roles(:app) do
puts "'goodnight, world'"
end
end
end
# Invoke hoge and bazz before deployment begins
before "deploy:starting", "myapp:hoge"
before "deploy:starting", "myapp:bazz"
The full list of built-in Capistrano task that you can use with before and after can be found here:
http://capistranorb.com/documentation/getting-started/flow/
I have whenever gem setup properly. How can I run that capistrano from my whenever schedule.rb?
my schedule.rb
every 1.minute, roles: [:app] do
# how to run here a capistrano task
# invoke 'my_app:test'
end
My capistrano task:
namespace :my_app do
desc 'test'
task :test do
on roles(:web) do
puts "the task runs"
end
end
end
Or should I move that task into a rake task. And should I run that rake task within whenever and capistrano?
Jan, you may find documentation very useful https://github.com/javan/whenever. The code example below - I just copied and edited it from the doc.
schedule.rb
# run this task only on servers with the :app role in Capistrano
# see Capistrano roles section below
every :day, at: '12:20am', roles: [:web] do
rake "app_server:task"
end
lib/tasks/test_task.rb
namespace :my_app do
desc 'test'
task :test do
puts "the task runs"
end
end
I believe it's easier to create Rake task and run it via Whenever. You can choose the Role, so basically you don't need to use Capistrano task (I believe you want to use it just because of Role).
I'd suggest your latter option, moving the logic to a rake task and executing it from both whenever and Capistrano. It'll be vastly easier and cleaner to do.
I have a scheduled job on rundeck (2.6.2).
This jobs run a script that needs an node environment variable available (like $HOME, $USER or $PWD. A custom one. ) for all user in the node/nodes.
I could use jobs options to solve this if I wanted trigger the job from API ( Or manually. Rundeck ask me for the option ) but is a scheduled job. I can't use Options -> Default Value because the jobs could run in nodes with different values for this environment variable.
There is any way to offers all / some node environment variables to rundeck to be used inside the scheduled jobs?
(I have thought in use Options -> Allowed Values -> Remote URL but is a mess. Too complicated to me requirement)
Thanks.
The easy way in my case has been to customize /etc/rundeck/profile adding into it all the stuff I wanted.
Seems a pretty good solution to me.
I succeeded to perform this by adding the following lines:
set -a
. /etc/environment
. /etc/profile
1) put those lines into the file: /etc/rundeck/profile
2) put those lines into a script step
Remark: I'm using only script steps in my rundeck and I'm always put this lines in the first line of the script step:
#!/usr/bin/env bash
I have a pretty long .sh file in my Capistrano tools directory that is intended to be executed on servers, not locally. Is there a simple way to execute this file on servers inside a Capistrano task without manually copying it on each server?
Assuming that the script is in your repository, you can create a custom task which allows you to do exactly that. Something like:
namespace :deploy do
desc 'Run custom command'
task :run_custom_command do
on roles(:app) do
# Your restart mechanism here, for example:
execute release_path.join('tools/command.sh')
end
end
before :publishing, :run_custom_command
end
Here is an tutorial how to pass parameters to an capistrano 3 task.
namespace :task do
desc 'Execute the specific cmd task'
task :invoke, :command do |task, args|
on roles(:app) do
execute :cmd, args[:command]
end
end
end
Can executed with:
$ cap staging "task:invoke[arg]"
How can i use this in my deploy.rb? The following does not work.
before :started, "task:invoke[arg]"
Not sure about before/after, but with Capistrano 3 you can always use the rake syntax and call task from within another task:
Rake::Task["mynamespace:mytask"].invoke(arg)
You can use invoke method:
before :started, :second_param do
invoke 'task:invoke', 'arg'
end
Also one thing which might be helpful, capistrano and rake allowing to execute task only first time, this might be common issue for task with parameters, cause you may reuse it with different value. To allow doing it you need to re-enable the task:
namespace :task do
desc 'Execute the specific cmd task'
task :invoke, :command do |task, args|
on roles(:app) do
execute :cmd, args[:command]
task.reenable # <--------- this how to re-enable it
end
end
end