1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Add role_properties helper method()

When defining properties for a role on a server, a useful convention
is to make the property name the same as the role. This method
facilitates easy retrieval and iteration through them.

See the updated documentation in capistrano.github.io
This commit is contained in:
Nick Townsend 2015-01-28 15:34:20 -08:00
parent 43c87cd9b6
commit 4b940c21b7
6 changed files with 66 additions and 1 deletions

View file

@ -15,6 +15,7 @@ Reverse Chronological Order:
* Refactored and simplified property filtering code (@townsen)
* Minor changes
* Add role_properties() method (see capistrano.github.io PR for doc) (@townsen)
* Add equality syntax ( eg. port: 1234) for property filtering (@townsen)
* Add documentation regarding property filtering (@townsen)
* Clarify wording and recommendation in stage template. (@Kriechi)

View file

@ -63,6 +63,10 @@ module Capistrano
servers.roles_for(names)
end
def role_properties_for(names, &block)
servers.role_properties_for(names, &block)
end
def primary(role)
servers.fetch_primary(role)
end

View file

@ -5,7 +5,7 @@ module Capistrano
class Filter
def initialize type, values = nil
raise "Invalid filter type #{type}" unless [:host,:role].include? type
av = Array(values)
av = Array(values).dup
@mode = case
when av.size == 0 then :none
when av.include?(:all) then :all

View file

@ -22,6 +22,23 @@ module Capistrano
s.select { |server| server.select?(options) }
end
def role_properties_for(rolenames)
roles = rolenames.to_set
rps = Set.new unless block_given?
roles_for(rolenames).each do |host|
host.roles.intersection(roles).each do |role|
[host.properties.fetch(role)].flatten(1).each do |props|
if block_given?
yield host, role, props
else
rps << (props || {}).merge( role: role, hostname: host.hostname )
end
end
end
end
block_given? ? nil: rps
end
def fetch_primary(role)
hosts = roles_for([role])
hosts.find(&:primary) || hosts.first

View file

@ -47,6 +47,10 @@ module Capistrano
env.roles_for(names.flatten)
end
def role_properties(*names, &block)
env.role_properties_for(names, &block)
end
def release_roles(*names)
if names.last.is_a? Hash
names.last.merge!({ :exclude => :no_release })

View file

@ -501,4 +501,43 @@ describe Capistrano::DSL do
end
describe 'role_properties()' do
before do
dsl.role :redis, %w[example1.com example2.com], redis: { port: 6379, type: :slave }
dsl.server 'example1.com', roles: %w{web}, active: true, web: { port: 80 }
dsl.server 'example2.com', roles: %w{web redis}, web: { port: 81 }, redis: { type: :master }
dsl.server 'example3.com', roles: %w{app}, primary: true
end
it 'retrieves properties for a single role as a set' do
rps = dsl.role_properties(:app)
expect(rps).to eq(Set[{ hostname: 'example3.com', role: :app}])
end
it 'retrieves properties for multiple roles as a set' do
rps = dsl.role_properties(:app, :web)
expect(rps).to eq(Set[{ hostname: 'example3.com', role: :app},{ hostname: 'example1.com', role: :web, port: 80},{ hostname: 'example2.com', role: :web, port: 81}])
end
it 'yields the properties for a single role' do
recipient = mock('recipient')
recipient.expects(:doit).with('example1.com', :redis, { port: 6379, type: :slave})
recipient.expects(:doit).with('example2.com', :redis, { port: 6379, type: :master})
dsl.role_properties(:redis) do |host, role, props|
recipient.doit(host, role, props)
end
end
it 'yields the properties for multiple roles' do
recipient = mock('recipient')
recipient.expects(:doit).with('example1.com', :redis, { port: 6379, type: :slave})
recipient.expects(:doit).with('example2.com', :redis, { port: 6379, type: :master})
recipient.expects(:doit).with('example3.com', :app, nil)
dsl.role_properties(:redis, :app) do |host, role, props|
recipient.doit(host, role, props)
end
end
end
end