Identify current host

2,343 views
Skip to first unread message

Gary Richardson

unread,
Jul 3, 2009, 8:47:35 PM7/3/09
to capis...@googlegroups.com
Hey,

Two part question that I haven't been able to answer:

1) can I get the current host a task is executing on? I've read some stuff about $CAPISTRANO:HOST$, but it doesn't seem to work for me
2) if I have an array of values (let's say an array that maps ec2 host names to ec2 instance id's), can I use this same method to look up something from that array?

For example:

task :example do
  instanceId = lookUpTable[hostname]
  run "somecommand -h #{hostname} -i #{instanceid}"
done

PS, the error I get when I run a task with $CAPISTRANO:HOST$ is:

  * executing "echo $CAPISTRANO:HOST$"
/usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/server_definition.rb:16:in `initialize': undefined method `match' for 101:Fixnum (NoMethodError)
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:80:in `new'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:80:in `wrap_server'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:98:in `wrap_list'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:97:in `map'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:97:in `wrap_list'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:59:in `to_ary'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:74:in `concat'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/role.rb:74:in `dynamic_servers'
         ... 28 levels...
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/lib/capistrano/cli/execute.rb:14:in `execute'
        from /usr/lib/ruby/gems/1.8/gems/capistrano-2.5.5/bin/cap:4
        from /usr/bin/cap:16:in `load'
        from /usr/bin/cap:16


Thanks!

Rafael G.

unread,
Jul 6, 2009, 6:31:17 AM7/6/09
to capis...@googlegroups.com
Gary Richardson wrote:
> Hey,
>
> Two part question that I haven't been able to answer:
>
> 1) can I get the current host a task is executing on? I've read some
> stuff about $CAPISTRANO:HOST$, but it doesn't seem to work for me
I tested this task and works for me:

task :host_name do
run "host $CAPISTRANO:HOST$"
end

What OS are you using? Could you paste your deploy.rb in
someplace(gist.github, pastie,...)?

> 2) if I have an array of values (let's say an array that maps ec2 host
> names to ec2 instance id's), can I use this same method to look up
> something from that array?

Capistrano uses ruby If you can do it with ruby you can do the same in a
capistrano task.

--
Rafa

Gary Richardson

unread,
Jul 6, 2009, 11:06:21 AM7/6/09
to capis...@googlegroups.com
Hmm. That's odd..$CAPISTRANO:HOST$ wasn't working for me on Friday. Must be them gremlins.

Is there another variable I can use to get the current host in the ruby code? This is what I'm trying to do:

  task :bootstrap, :roles => [:master] do
        # instanceids is an array containing hostname => instanceid
id = instanceids["$CAPISTRANO:HOST$"]
run "register_host -H $CAPISTRANO:HOST$ -s #{id}"
  end

Obviously, $CAPISTRANO:HOST$ doesn't interpolate on the id = instanceids[] line.

Thanks!

Jamis Buck

unread,
Jul 6, 2009, 11:35:08 AM7/6/09
to capis...@googlegroups.com
On Mon, Jul 6, 2009 at 9:06 AM, Gary
Richardson<gary.ri...@gmail.com> wrote:
> Hmm. That's odd..$CAPISTRANO:HOST$ wasn't working for me on Friday. Must be
> them gremlins.
> Is there another variable I can use to get the current host in the ruby
> code? This is what I'm trying to do:

Short answer: no.

Longer answer: yes, kind of.

Keep in mind one key concept: capistrano does not run a command on
each server sequentially; it runs the commands on all servers in
parallel. Thus, within a task, there is no such thing as a "current
host". What you have is a set of servers that match the current task,
and all commands invoked within that task will run in parallel on that
set of servers.

So, what you can do is get the list of matching servers:

task :bootstrap, :roles => :master do
servers = find_servers_for_task(current_task)
servers.each do |server|
puts "host: #{server.host}"
end
end

- Jamis

Rafael G.

unread,
Jul 6, 2009, 11:42:13 AM7/6/09
to capis...@googlegroups.com

Rafael G.

unread,
Jul 6, 2009, 11:43:00 AM7/6/09
to capis...@googlegroups.com
Sorry, I didn't saw your reply :-)
--
Rafa

Gary Richardson

unread,
Jul 6, 2009, 5:35:02 PM7/6/09
to capis...@googlegroups.com
Ok, I'm moving along here. This is what I've come up with:

task :host_name do
  servers = find_servers_for_task(current_task)
  servers.each do |server|
set :myServer, server.host
set :myId, instanceids[myServer]
real_host_name(:hosts => [myServer])
  end
end

task :real_host_name do
  run "echo #{myServer} - #{myId}"
end

The problem is that "real_host_name(:hosts => [myServer])" doesn't do what I expect it to :( -- real_host_name ends up getting called for all hosts in the current role.

Is there a way to change :hosts/:roles for a sub-task? Or possible call run with a limited subset of hosts?

Is there a better way of doing this?

Thanks!
Reply all
Reply to author
Forward
0 new messages