What is the best practice for handling common dependencies.

1 view
Skip to first unread message

Tim Uckun

Nov 2, 2009, 5:54:49 PM11/2/09
to autom...@googlegroups.com
I have the following scenario.

I have a rails app which runs in many flavors like "production"
"staging" "qa" "demo" etc.

Each one has it's own config files things like crontab, custom daemon
start stop scripts, httpd config files etc. Needless to say they have
lots of common requirements too like ruby, rails, apache, passenger

Ideally things should be installed in order like this

lots-of-packages-like-build-essential, apache, passenger, postgres,
ruby, lots-of-gems, rails, app-common, app-staging etc...

What is the best practice for something like this?

If I create tags for each one of those things I can't be guaranteed
they run in order right?

I could call "invoke blah" from individual recipes but that seems
wasteful to keep running the same recipe over and over.

The only thing I can think of is the maybe use the "require"
mechanism. That would only call the common recipe once right?

Is there another way to do accomplish this?

Igal Koshevoy

Nov 2, 2009, 7:33:37 PM11/2/09
to autom...@googlegroups.com
Some quick perspective since you've been working heavily with tools that
use different paradigms:
- Puppet is a declarative system where you create a type to do
repetitive work, connect resources with dependencies, and let the
interpreter guess what order to run commands.
- AutomateIt is an imperative system where you create methods to do
repetitive work, call these as needed, and organize code in the order
you want the interpreter to run it.


If I was doing the task you described, I'd create a top-level "all.rb"
recipe that calls all the other recipes.

In this top-level recipe, I'd invoke a bunch of generic recipes that
setup the basics of Apache, Passenger, PostgreSQL, etc, for this Rails
application server role, e.g.:

if tagged?(:rails_server)
invoke 'base_apache'
invoke 'base_passenger'

Towards the end of this "all.rb" recipe, I'd have it invoke a custom
recipe for setting up the individual Rails apps. If these Rails apps are
very similar, I'd create a method (via Ruby's lambda or file in the
project's "lib" directory) that I can call with arguments to do all the
repetitive work of creating each app's directories, databases, Apache
sites and such, e.g.:

setup_my_rails_app_for("staging") if tagged?(:rails_staging_server)
setup_my_rails_app_for("qa") if tagged?(:rails_qa_server)


You can see how I'm using a custom "apache_manager" to do the redundant
install/enable/reload work for setting up a default apache site:

And then in a Rails app:


And here's the ApacheManager library that I'm using to do this, look
particularly at the "install_site" method:

You'd basically want to write something a higher-level wrapper.

Does that make sense?

Reply all
Reply to author
0 new messages