On 26 Aug, 17:04, Andres Paglayan <[email protected]> wrote:
> For a bunch of identical applications running on virtual hosts on the
> same machine
> (apache and mod_rails)
> some time ago Jamis suggested an approach along the lines of
>
> task :install_1 do
>     set :deploy_to,  "/home/rails/install_1/#{application}"
> end
> ...
> task :install_n do
>     set :deploy_to,  "/home/rails/install_n/#{application}"
> end
>
> Which works fine,
> but there's some manual job involved each time a new instance is added,
>
> My need is to deploy to the array of virtual servers on the single
> physical machine,
> changing several things bases solely in the user => pass hash
>
> given {:user_1 => db_pass_1, :user_2 => db_pass_2, :user_n =>
> db_pass_n }.each  do  |user_x, pass_x|
>
> Where data about the repository remains 'static' but
> I need to set all the following accordingly for each user:
>
> set deploy_to: "/home/#{user_x}/apps/#{application}"  
>
> set :app, "#{user_x}.my_domain.com"
> set :web, "#{user_x}.my_domain.com"
> set :db, "#{user_x}.my_domain.com"
>
> plus then modify each of the conf/database.yml accordingly
> like in
>
> production:
>    adapter: mysql
>    encoding: utf8
>    database: #{user_x}_app_production
>    username: #{user_x}
>    password: #{pass_x}
>
> and I'd like all of that to happen when I say
> cap deploy:update
> I would even give up to add,
> cap deploy:configure_database

I'm not sure how to do this purely in cap, it seems like it'd be a lot
of screw around to get it to work. What I would do is write a rake
task that does the iteration and calls out to cap. It'd probably be
wayyy easier than trying to man-handle cap into doing what you're
asking. Though I hope someone else proves me wrong.

To deploy:
rake deploy

==============================
deploy.rake
task deploy do
  users = {:user_1 => db_pass_1, :user_2 => db_pass_2, :user_n =>
db_pass_n }
  users.each do |user, pass|
    system("cap deploy:update -S user=#{user} -S pass=#{pass}") or
abort("Could not deploy to #{user}")
  end
end
==============================

Then in cap I'd handle the different variables:

==============================
deploy.rb

def validate_credentials
  fail("Cannot deploy without giving user credentials") unless
variables[:user] && variables[:password]
end

validate_credentials

set :user, variables[:user]
set :password, variables[:password]

logger.info("Deploying to #{user}")

set deploy_to: "/home/#{user}/apps/#{application}"

set :app, "#{user}.my_domain.com"
set :web, "#{user}.my_domain.com"
set :db, "#{user}.my_domain.com"

# and configure it to write out the database.yml
# some other options:
# * manually put the database.yml in the #{shared_path}/config/
database.yml and just symlink
#   This has the big benefit of only keeping the credentials on the
server itself and not having
#   to manage them outside of that (Assuming they're relatively
static, I would do that)
# * automatically put the creds in #{shared_path}/config/database.yml
and symlink it in
namespace :db do
  task :update_config, :roles => :app, :except => { :no_release =>
true } do
    yaml = <<EOF
production:
  adapter: mysql
  encoding: utf8
  database: #{user}_app_production
  username: #{user}
  password: #{pass}
EOF

    # now get that file into #{release_path}/config/database.yml
    # leave that up to you
    # I'd probably write to a temp file and upload it (should make
sure to delete it afterwards to
    # avoid leaving a credentials file in tmp)
    # or echo it directly into a file on that box (but I can never get
multiline stuff to work
    # properly when doing a run("..."))
  end

  after 'deploy:update_code', 'db:update_config'
end
==============================

The way I've been managing config files like this is a bit like this
approach, but I write them all and then upload them all at once:
require 'ftools'
namespace :config do
  task :build do
    File.mkdir_p temp_config_dir
    # this is the place to hook after when creating a config file
  end

  task :update do
    # upload contents of temp_config_dir to #{release_path}/config
  end

  before 'config:update', 'config:build'
  after 'deploy:update_code', 'config:update'
end

task :some_config do
  # write file1 to temp_config_dir
end
task :some_other_config do
 # write file2 to temp_config_dir
end
after 'config:build', 'some_config'
after 'config:build', 'some_other_config'

# both file1 and file2 will automatically get uploaded to #
{release_path}/config/[file1, file2]

But we have a bunch of config files we write (database, memcached,
sphinx, ...) and that approach may be overkill for you (though it
probably would be something that could go in capistrano-ext if anyone
likes it).
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Capistrano" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.co.uk/group/capistrano?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to