David,

Perhaps I'm not understanding what you're mean, but the current version of Capistrano allows you to do things like this:

  task :foo, :roles => defer { something_that_computes_roles } do
  end

The "defer" method is just an alias for lambda that Capistrano adds. The block there just needs to return the name of a role (or an array of role names). That block is then evaluated at the moment that the task is run.

- Jamis

On Jan 11, 2008, at 1:29 PM, David Masover wrote:


Working on a way to use Capistrano to deploy to ec2. I know about
Capsize, but decided that I didn't want to hardcode image and instance
IDs anywhere -- particularly as Capistrano itself will eventually be
creating those itself.

The first roadblock was: I can use variables-as-blocks to define
things like the list of current instances, the latest instance, etc.
(Variables, not functions or tasks, because I figure that information
isn't going to change over the course of a single invocation of cap,
unless I change it myself.)

But I cannot define roles-as-blocks, and I want to find roles out from
the results of ec2-describe-instances (and probably other things as
well). So, I needed dynamic roles.

I'm completely new to the Rails and Capistrano community, so I'm not
sure what style conventions I should use, where to send patches, etc.
Here's the hack I have so far:

Capistrano::Configuration::Roles.module_eval do
        alias_method :orig_role, :role
        def role(which, *args, &block)
                if !block_given? && args.empty? || block_given? && !args.empty?
                        raise ArgumentError, "you must specify exactly one of 
either a
value or a block"
                end
                if block_given? then
                        which = which.to_sym
                        @roles[which] = block
                else
                        # I apologize for this one-liner
                        orig_role(which, args.map{|item| String === item ?
Capistrano::ServerDefinition.new(item) : item})
                end
        end
end

Capistrano::Configuration::Servers.module_eval do
        alias_method :find_servers_orig, :find_servers
        def find_servers(options={})
                hosts = server_list_from(ENV['HOSTS'] || options[:hosts])

                if hosts.any?
                        hosts.uniq
                else
                        roles = role_list_from(ENV['ROLES'] || options[:roles] 
||
self.roles.keys)
                        roles.each { |role|
                                target = self.roles[role]
                                if target.respond_to?(:call)
                                        self.roles[role] = target.call.map { 
|server|
                                                String === server ? 
ServerDefinition.new(server, {}) : server
                                        }
                                end
                        }
                        find_servers_orig(options)
                end
        end
end
--~--~---------~--~----~------------~-------~--~----~
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/capistrano
-~----------~----~----~----~------~----~------~--~---


Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to