8

How would I reference the current server in a Capistrano task? I want to curl a local file to clear the APC cache but the server does not listen on localhost so I need the server's IP address.

For instance,

role :web, "1.1.1.1", "2.2.2.2", "3.3.3.3"

task :clear_apc, :role => :web do
    run "curl http://#{WHAT_DO_I_PUT_HERE}/deploy/clearAPC.php"
end

What variable would I use so that when the task is run on 1.1.1.1 it curls http://1.1.1.1/deploy/clearAPC.php but when run on 2.2.2.2 it calls curls http://2.2.2.2/deploy/clearAPC.php

Brad Dwyer
  • 6,305
  • 8
  • 48
  • 68

6 Answers6

29

In Capistrano, tasks don't get executed once for each server, run executes your command on each server. Here is what you should do instead:

task :clear_apc, :role => :web do
    find_servers_for_task(current_task).each do |current_server|

        run "curl http://#{current_server.host}/deploy/clearAPC.php", :hosts => current_server.host

    end
end

The accepted answer will work, but this one lets you access the servers as variables/methods

user1158559
  • 1,954
  • 1
  • 18
  • 23
11

There's the magical $CAPISTRANO:HOST$

run "curl http://$CAPISTRANO:HOST$/deploy/clearAPC.php" 

should do exactly what you want.

note: don't use it as a variable via string interpolation, capistrano will just replace the $CAPISTRANO:HOST$ in the string itself.

That's a very weird and (afaik) undocumented feature :-)

Pascal
  • 5,879
  • 2
  • 22
  • 34
  • This looks really hacky. Why didn't the Capistrano guys make it a method? – user1158559 Nov 16 '12 at 12:22
  • maybe @leehambley knows the answer ;) I'll point him to this question – Pascal Nov 16 '12 at 16:08
  • user1158559 has a much better answer, though it's not the accepted one. – Nate Mar 26 '13 at 15:02
  • @Nate the question was how to access the hostname and that's the fastest way. Could you please elaborate why you prefere the way longer method below over the my solution, considering the original question? – Pascal Mar 26 '13 at 15:46
  • Because good lord, is $CAPISTRANO:HOST$ ugly as sin. It looks like magic. Making the loop explicit seems like a good idea to me. It is worth noting: it is documented here: https://github.com/capistrano/capistrano/wiki/2.x-DSL-Action-Invocation-Run – Nate Mar 26 '13 at 17:19
  • @Nate I never said it's beautiful, but I answered the original question. I do however respect your opinion, I just didn't see the reason for the downvote because the answer is 100% legit – Pascal Mar 27 '13 at 10:15
  • Sigh, you're right; it really didn't deserve a downvote. However, SO doesn't seem to let me undownvote it :/ – Nate Mar 27 '13 at 15:44
  • Technically the OP asked what should be put inside his ruby string interpolation and what variable he should use! :) – user1158559 Sep 06 '13 at 01:07
3
current_host = capture("echo $CAPISTRANO:HOST$").strip
Florian Eck
  • 245
  • 1
  • 16
1

Capistrano 3 - server is available as an object, with set of properties, in the roles block :

on roles(:app) do |server|

So for example to pass the hostname property to docker compose

  on roles(:app)  do |server|
    execute "docker-compose --build-arg SOME_HOST_NEEDED=#{server.hostname} ......
  end
aqwan
  • 470
  • 4
  • 6
0

I wanted to know the current server I was deploying to, so that I could send a message to campfire. This is what I was able to figure out, though I'm sure there is a better way

 actions = current_task.namespace.parent.logger.instance_variable_get('@options')[:actions]
 message = "I am deploying #{fetch(:latest_release).split('/').last} using cap #{actions.join(' ')}"

so when I deploy it posts this to campfire I am deploying 20121206154442 using cap QA2 campfire:notify deploy deploy:flex_master

J_McCaffrey
  • 1,455
  • 12
  • 15
0

capistrano (2.13.5) required

puts current_task.namespace.logger.instance_variable_get('@base_logger').instance_variable_get('@options')[:actions].join(' ')

figured this out by

puts current_task.namespace.logger.inspect