Hi Dan,
I had a very similar need, and I'll post the code (hack?) below that
helped me get what I wanted. The way the ROLES variable works never
made intuitive sense to me. Instead of overriding what roles are
specified for a given task, my feeling is that it should just run the
tasks/subtasks that specify that role and ignore the others. I've
never had a situation where the current implementation of the ROLES
variables has helped as almost all my tasks have subtasks.
So I made simple modifications to both the run method and the
find_servers method. Now that I think about it, this will probably
have problems on sub-sub-tasks, but it's worked great for what I've
needed as I usually only specify a :roles => XXX for a task that comes
at the bottom of the execution chain. Now that I'm filtering out any
tasks that are not specified for the current ROLESFILTER, it's
probable that there will be tasks that try to execute but have all
their servers "filtered" out. So you need to catch any
"NoMatchingServersError" in the run method to prevent cap from dying.
# allow a ROLESFILTER to be passed which only executes tasks that
already specify that role
module Capistrano::Configuration::Servers
alias_method :old_find_servers, :find_servers
def find_servers(*args)
servers = old_find_servers(*args)
if ENV['ROLESFILTER']
filtered_roles = role_list_from(ENV['ROLESFILTER'])
filtered_roles_servers = roles.inject([]) { |list, role|
list.concat(self.roles[role]) }
end
servers = servers & filtered_roles_servers
end
end
# Now doesn't die if can't find a server for the role
module Capistrano::Configuration::Actions::Invocation
alias_method :old_run, :run
def run(*args)
begin
old_run(*args)
rescue Capistrano::NoMatchingServersError => error
puts " ** Skipped task"
end
end
end
HTH.
stevie
On 4 Oct, 14:42, Dan Powell <[EMAIL PROTECTED]> wrote:
> It's actually the ROLES variable I'm trying to set. Basically, my
> application (not a Rails application) has a few tiers that each have
> different deployment needs. For example, the directories from
> shared_path that I need to link into latest_release vary somewhat. To
> accomplish this, I tried creating a symlink_tiera and symlink_tierb
> task each called by the symlink task. This works fine when I'm
> running the deploy (or symlink directly) task with no ROLES
> restrictions - it runs the symlink_tiera instructions only on the
> tiera hosts and the symlink_tierb instructions only on the tierb
> hosts. However, if I specify ROLES=tiera when I run cap, it runs the
> instructions for tiera and tierb on the tiera hosts, and nothing on
> the tierb hosts. The desired behavior would be for it to run only the
> tiera instructions and only on the tiera hosts, and not run any of the
> tierb instructions anywhere and do nothing with the tierb hosts.
>
> Is there any reason that subtasks should not observe the role
> declarations specified in the environment? It seems like if a task is
> set to only run on certain roles you would never want it to run on
> hosts of a different role, and that that task should simply be
> skipped. This particularly seems inconsistent with the behavior I
> observe when I don't specify a ROLES environment variable - why would
> it not observe the role declarations in this case but not when I
> specify a ROLES list?
>
> I suppose a concrete example might be if I am using a ferret DRb on a
> separate box, I might want my stop and start tasks to run the
> appropriate commands on a ferret role while still running the usual
> mongrel commands on the app role. I would never want to run the
> stop_ferret task on the app role, nor to run the start_mongrel task on
> the ferret role.
>
> On Oct 4, 1:09 pm, Jamis Buck <[EMAIL PROTECTED]> wrote:
>
> > Specifying either ROLES or HOSTS will use the given roles or hosts
> > for all tasks that are executed, basically overriding whatever roles/
> > hosts declarations any tasks have. This is mostly only useful for
> > simple tasks, which do not themselves invoke other tasks, and was
> > intended originally to make it possible to do things like
> > deploy:setup on only a subset of your servers.
>
> > I'm open to suggestions about how to make this more useful. Dan, can
> > you tell me more of what you're trying to do with the HOSTS
> > environment variable, and what the behavior you expect is?
>
> > - Jamis
>
> > On Oct 4, 2007, at 10:32 AM, Dan Powell wrote:
>
> > > I can see how that might help with HOST restrictions where you want to
> > > change hosts in the middle, but here my restrictions are role based
> > > and the hosts for those roles are not changing at runtime.
>
> > > Based on Jamis' comment in that thread "If you set the HOSTS
> > > environment variable, all tasks will use it,
> > > instead of whatever hosts list they might have otherwise. " I even
> > > tried explicitly hard coding setting the ROLES variable, but that
> > > didn't really help anything. Perhaps that's a HOSTS vs ROLES
> > > behavior, I'm not sure. Should I try to set the HOSTS variable with
> > > the hosts for the ROLES I've specified? Again, I'm not changing HOSTS
> > > (or ROLES) in midstream, so I'm not sure why "changing" these
> > > variables to the same value as the one specified when invoking cap
> > > would help, unless there is some destructive processing done to the
> > > ROLES set on startup that I'm now having to override in my task.
>
> > > On Oct 4, 9:54 am, Joe <[EMAIL PROTECTED]> wrote:
> > >> Dan,
>
> > >> Seehttp://groups.google.com/group/capistrano/browse_thread/
> > >> thread/c4885d....
>
> > >> Joe
>
> > smime.p7s
> > 3KDownload
--~--~---------~--~----~------------~-------~--~----~
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/capistrano
-~----------~----~----~----~------~----~------~--~---