Executing a task once locally, but copying to all remote hosts

60 views
Skip to first unread message

Robin Bowes

unread,
Dec 2, 2009, 8:24:48 AM12/2/09
to Capistrano
Hi,

I'm using railsless deploy, and have this task to generate a config file
locally, and copy it to all hosts:

desc <<-DESC
Create config file & copy to release path
DESC
task :create_copy_config_file, :roles => [:web] do
print " Creating config file.\n"
file = 'files/counter.php'
system "scripts/create_config #{file}"
print " Copying config file.\n"
upload(file, "#{release_path}/www/counter.php")
end

I suspect that will re-create the config file once for every host?

If so, how would I just generate the config file once locally, then copy
to all hosts?

It's not so bad for this simple case but I have another task to write
that grabs ~200M of GeoIP updates and I only want to execute that once!

R.

Lee Hambley

unread,
Dec 2, 2009, 9:16:36 AM12/2/09
to capis...@googlegroups.com
You're doing it wrong, try this

def generate_config_file
     # implement me in pure, standard ruby!
     file_generated ||= system('script/system')
end

-- Lee Hambley

Twitter: @leehambley | @capistranorb

Robin Bowes

unread,
Dec 2, 2009, 9:42:19 AM12/2/09
to Capistrano
On 02/12/09 14:16, Lee Hambley wrote:
> You're doing it wrong, try this
>
> def generate_config_file
> # implement me in pure, standard ruby!
> file_generated ||= system('script/system')
> end

I don't know ruby all that well, but I suspect that will not re-generate
the file when the deploy runs if it already exists?

Also, that just generates the file - how do I tie that in to
distributing it?

Thanks!

R.

Robin Bowes

unread,
Dec 2, 2009, 9:49:27 AM12/2/09
to Capistrano
On 02/12/09 13:24, Robin Bowes wrote:

> It's not so bad for this simple case but I have another task to write
> that grabs ~200M of GeoIP updates and I only want to execute that once!

In this case, what I need to do is run the following commands:

# First make sure /usr/share/GeoIP/ is up-to-date locally
geoippudate
# Then update twenty nodes
for node in node${seq -w 1 20} ; do
rsync -avn /usr/share/GeoIP/ root@$node:/usr/share/GeoIP
done

How can I capify this?

R.

Lee Hambley

unread,
Dec 2, 2009, 10:04:07 AM12/2/09
to capis...@googlegroups.com
The idea would be that file_generated would be boolean,

# deploy.rb

@file_generated = false


def generate_config_file
     # implement me in pure, standard ruby!
     @file_generated ||= system('script/system')
end

System, should - once generate the file


-- Lee Hambley

Twitter: @leehambley | @capistranorb
Blog: http://lee.hambley.name/
Working with Rails: http://is.gd/1s5W1


2009/12/2 Robin Bowes <robin...@robinbowes.com>

R.

--
* You received this message because you are subscribed to the Google Groups "Capistrano" group.
* To post to this group, send email to capis...@googlegroups.com
* To unsubscribe from this group, send email to capistrano+...@googlegroups.com For more options, visit this group at http://groups.google.com/group/capistrano?hl=en

Robin Bowes

unread,
Dec 2, 2009, 10:09:51 AM12/2/09
to Capistrano
On 02/12/09 15:04, Lee Hambley wrote:
> The idea would be that file_generated would be boolean,
>
> # deploy.rb
>
> @file_generated = false
>
> def generate_config_file
> # implement me in pure, standard ruby!
> @file_generated ||= system('script/system')
> end
>
> System, should - once generate the file

You appear to be answering the question before last :)

Thanks - I'll give that a go.

> In this case, what I need to do is run the following commands:
>
> # First make sure /usr/share/GeoIP/ is up-to-date locally
> geoippudate
> # Then update twenty nodes
> for node in node${seq -w 1 20} ; do
> rsync -avn /usr/share/GeoIP/ root@$node:/usr/share/GeoIP
> done
>
> How can I capify this?

How about this?

R.

Lee Hambley

unread,
Dec 2, 2009, 10:28:32 AM12/2/09
to capis...@googlegroups.com
I'd have something like this:

task :upload_config_file, :roles => [:all] do
   generate_config_file
   put() # see our docs for put.
end


-- Lee Hambley

Twitter: @leehambley | @capistranorb
Blog: http://lee.hambley.name/
Working with Rails: http://is.gd/1s5W1


2009/12/2 Robin Bowes <robin...@robinbowes.com>
On 02/12/09 15:04, Lee Hambley wrote:

R.

Donovan Bray

unread,
Dec 2, 2009, 11:05:44 AM12/2/09
to capis...@googlegroups.com
Memoize the block around the system call

http://6brand.com/ruby-speedup-memoize-those-methods.html

On Dec 2, 2009, at 5:24 AM, Robin Bowes <robin...@robinbowes.com>
wrote:

Robin Bowes

unread,
Dec 2, 2009, 1:26:52 PM12/2/09
to Capistrano
OK, this seems to work:

@file_generated = false
def generate_config_file
# implement me in pure, standard ruby!
@file_generated ||= system("scripts/create_config
files/counter.php")
end

desc <<-DESC
Create counter.php config file & copy to release path
DESC
task :update_config_file, :roles => [:web] do
generate_config_file
print " Copying config file.\n"
upload("files/counter.php", "#{release_path}/www/counter.php")
end


However, you'll noticed that the scratch file name (files/counter.php)
is specified in two places. Can I somehow define that in a var that can
be used un the system call *and* in the cap upload command?

R.

Robin Bowes

unread,
Dec 2, 2009, 1:27:44 PM12/2/09
to Capistrano
On 02/12/09 18:17, Lee Hambley wrote:
> Yes, of course, just make it a local variable
>

[taking back to list]

Er, "just make it a local variable" ? For example... ?

R.

Lee Hambley

unread,
Dec 2, 2009, 2:15:57 PM12/2/09
to capis...@googlegroups.com

Robin Bowes

unread,
Dec 2, 2009, 2:19:37 PM12/2/09
to Capistrano
On 02/12/09 19:15, Lee Hambley wrote:
> Robin https://gist.github.com/f9aca125524fa03c45ef

Hmmm, I could've sworn I tried that.

Thanks!

R.

Lee Hambley

unread,
Dec 2, 2009, 2:21:28 PM12/2/09
to capis...@googlegroups.com
Yep, but these things happen!
Reply all
Reply to author
Forward
0 new messages