capistrano 3.3.5 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +36 -2
- data/README.md +30 -287
- data/capistrano.gemspec +0 -1
- data/features/sshconnect.feature +11 -0
- data/features/step_definitions/assertions.rb +6 -2
- data/features/step_definitions/setup.rb +4 -0
- data/lib/capistrano/configuration.rb +5 -1
- data/lib/capistrano/configuration/filter.rb +2 -2
- data/lib/capistrano/configuration/server.rb +15 -53
- data/lib/capistrano/configuration/servers.rb +26 -7
- data/lib/capistrano/deploy.rb +0 -1
- data/lib/capistrano/dsl.rb +2 -2
- data/lib/capistrano/dsl/env.rb +9 -1
- data/lib/capistrano/dsl/paths.rb +1 -1
- data/lib/capistrano/git.rb +1 -1
- data/lib/capistrano/tasks/deploy.rake +0 -1
- data/lib/capistrano/templates/Capfile +1 -1
- data/lib/capistrano/templates/deploy.rb.erb +3 -3
- data/lib/capistrano/templates/stage.rb.erb +31 -15
- data/lib/capistrano/version.rb +1 -1
- data/spec/integration/dsl_spec.rb +86 -113
- data/spec/lib/capistrano/configuration/filter_spec.rb +9 -3
- data/spec/lib/capistrano/configuration/server_spec.rb +34 -3
- data/spec/lib/capistrano/configuration/servers_spec.rb +37 -1
- data/spec/lib/capistrano/configuration_spec.rb +11 -0
- data/spec/lib/capistrano/dsl/paths_spec.rb +162 -41
- data/spec/support/Vagrantfile +17 -6
- data/spec/support/tasks/root.rake +11 -0
- data/spec/support/test_app.rb +1 -1
- metadata +7 -17
@@ -106,10 +106,14 @@ When(/^an error is raised$/) do
|
|
106
106
|
run_vagrant_command(test_file_exists(error))
|
107
107
|
end
|
108
108
|
|
109
|
-
Then(/contains "(
|
109
|
+
Then(/contains "([^"]*)" in the output/) do |expected|
|
110
110
|
expect(@output).to include(expected)
|
111
111
|
end
|
112
112
|
|
113
|
-
Then(/
|
113
|
+
Then(/the output matches "([^"]*)" followed by "([^"]*)"/) do |expected, followedby|
|
114
|
+
expect(@output).to match(/#{expected}.*#{followedby}/m)
|
115
|
+
end
|
116
|
+
|
117
|
+
Then(/doesn't contain "([^"]*)" in the output/) do |expected|
|
114
118
|
expect(@output).not_to include(expected)
|
115
119
|
end
|
@@ -27,6 +27,10 @@ Given(/^a custom task to generate a file$/) do
|
|
27
27
|
TestApp.copy_task_to_test_app('spec/support/tasks/database.rake')
|
28
28
|
end
|
29
29
|
|
30
|
+
Given(/^a task which executes as root$/) do
|
31
|
+
TestApp.copy_task_to_test_app('spec/support/tasks/root.rake')
|
32
|
+
end
|
33
|
+
|
30
34
|
Given(/config stage file has line "(.*?)"/) do |line|
|
31
35
|
TestApp.append_to_deploy_file(line)
|
32
36
|
end
|
@@ -63,6 +63,10 @@ module Capistrano
|
|
63
63
|
servers.roles_for(names)
|
64
64
|
end
|
65
65
|
|
66
|
+
def role_properties_for(names, &block)
|
67
|
+
servers.role_properties_for(names, &block)
|
68
|
+
end
|
69
|
+
|
66
70
|
def primary(role)
|
67
71
|
servers.fetch_primary(role)
|
68
72
|
end
|
@@ -82,7 +86,7 @@ module Capistrano
|
|
82
86
|
sshkit.backend.configure do |backend|
|
83
87
|
backend.pty = fetch(:pty)
|
84
88
|
backend.connection_timeout = fetch(:connection_timeout)
|
85
|
-
backend.ssh_options =
|
89
|
+
backend.ssh_options = (backend.ssh_options || {}).merge(fetch(:ssh_options,{}))
|
86
90
|
end
|
87
91
|
end
|
88
92
|
end
|
@@ -5,7 +5,7 @@ module Capistrano
|
|
5
5
|
class Filter
|
6
6
|
def initialize type, values = nil
|
7
7
|
raise "Invalid filter type #{type}" unless [:host,:role].include? type
|
8
|
-
av = Array(values)
|
8
|
+
av = Array(values).dup
|
9
9
|
@mode = case
|
10
10
|
when av.size == 0 then :none
|
11
11
|
when av.include?(:all) then :all
|
@@ -32,7 +32,7 @@ module Capistrano
|
|
32
32
|
when Regexp then v
|
33
33
|
else
|
34
34
|
vs = v.to_s
|
35
|
-
vs =~ %r{^/(.+)/$} ? Regexp.new($1) : vs
|
35
|
+
vs =~ %r{^/(.+)/$} ? Regexp.new($1) : %r{^#{vs}$}
|
36
36
|
end
|
37
37
|
end
|
38
38
|
Regexp.union av
|
@@ -25,8 +25,19 @@ module Capistrano
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def select?(options)
|
28
|
-
|
29
|
-
|
28
|
+
options.each do |k,v|
|
29
|
+
callable = v.respond_to?(:call) ? v: ->(server){server.fetch(v)}
|
30
|
+
result = case k
|
31
|
+
when :filter, :select
|
32
|
+
callable.call(self)
|
33
|
+
when :exclude
|
34
|
+
!callable.call(self)
|
35
|
+
else
|
36
|
+
self.fetch(k) == v
|
37
|
+
end
|
38
|
+
return false unless result
|
39
|
+
end
|
40
|
+
return true
|
30
41
|
end
|
31
42
|
|
32
43
|
def primary
|
@@ -51,7 +62,7 @@ module Capistrano
|
|
51
62
|
end
|
52
63
|
|
53
64
|
def matches?(other)
|
54
|
-
|
65
|
+
hostname == other.hostname
|
55
66
|
end
|
56
67
|
|
57
68
|
private
|
@@ -87,7 +98,7 @@ module Capistrano
|
|
87
98
|
@properties[key]
|
88
99
|
end
|
89
100
|
|
90
|
-
def respond_to?(method)
|
101
|
+
def respond_to?(method, include_all=false)
|
91
102
|
@properties.has_key?(method)
|
92
103
|
end
|
93
104
|
|
@@ -115,55 +126,6 @@ module Capistrano
|
|
115
126
|
|
116
127
|
end
|
117
128
|
|
118
|
-
class Selector
|
119
|
-
def initialize(options)
|
120
|
-
@options = options
|
121
|
-
end
|
122
|
-
|
123
|
-
def self.for(options)
|
124
|
-
if options.has_key?(:exclude)
|
125
|
-
Exclusive
|
126
|
-
else
|
127
|
-
self
|
128
|
-
end.new(options)
|
129
|
-
end
|
130
|
-
|
131
|
-
def callable
|
132
|
-
if key.respond_to?(:call)
|
133
|
-
key
|
134
|
-
else
|
135
|
-
->(server) { server.fetch(key) }
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def call(server)
|
140
|
-
callable.call(server)
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
attr_reader :options
|
145
|
-
|
146
|
-
def key
|
147
|
-
options[:filter] || options[:select] || all
|
148
|
-
end
|
149
|
-
|
150
|
-
def all
|
151
|
-
->(server) { :all }
|
152
|
-
end
|
153
|
-
|
154
|
-
class Exclusive < Selector
|
155
|
-
|
156
|
-
def key
|
157
|
-
options[:exclude]
|
158
|
-
end
|
159
|
-
|
160
|
-
def call(server)
|
161
|
-
!callable.call(server)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
end
|
166
|
-
|
167
129
|
end
|
168
130
|
end
|
169
131
|
end
|
@@ -8,7 +8,14 @@ module Capistrano
|
|
8
8
|
include Enumerable
|
9
9
|
|
10
10
|
def add_host(host, properties={})
|
11
|
-
|
11
|
+
new_host = Server[host]
|
12
|
+
if server = servers.find { |s| s.matches? new_host }
|
13
|
+
server.user = new_host.user if new_host.user
|
14
|
+
server.port = new_host.port if new_host.port
|
15
|
+
server.with(properties)
|
16
|
+
else
|
17
|
+
servers << new_host.with(properties)
|
18
|
+
end
|
12
19
|
end
|
13
20
|
|
14
21
|
def add_role(role, hosts, options={})
|
@@ -22,6 +29,23 @@ module Capistrano
|
|
22
29
|
s.select { |server| server.select?(options) }
|
23
30
|
end
|
24
31
|
|
32
|
+
def role_properties_for(rolenames)
|
33
|
+
roles = rolenames.to_set
|
34
|
+
rps = Set.new unless block_given?
|
35
|
+
roles_for(rolenames).each do |host|
|
36
|
+
host.roles.intersection(roles).each do |role|
|
37
|
+
[host.properties.fetch(role)].flatten(1).each do |props|
|
38
|
+
if block_given?
|
39
|
+
yield host, role, props
|
40
|
+
else
|
41
|
+
rps << (props || {}).merge( role: role, hostname: host.hostname )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
block_given? ? nil: rps
|
47
|
+
end
|
48
|
+
|
25
49
|
def fetch_primary(role)
|
26
50
|
hosts = roles_for([role])
|
27
51
|
hosts.find(&:primary) || hosts.first
|
@@ -33,13 +57,8 @@ module Capistrano
|
|
33
57
|
|
34
58
|
private
|
35
59
|
|
36
|
-
def server(host)
|
37
|
-
new_host = Server[host]
|
38
|
-
servers.find { |server| server.matches? new_host } || new_host
|
39
|
-
end
|
40
|
-
|
41
60
|
def servers
|
42
|
-
@servers ||=
|
61
|
+
@servers ||= []
|
43
62
|
end
|
44
63
|
|
45
64
|
def extract_options(array)
|
data/lib/capistrano/deploy.rb
CHANGED
data/lib/capistrano/dsl.rb
CHANGED
@@ -51,8 +51,8 @@ module Capistrano
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def on(hosts, options={}, &block)
|
54
|
-
|
55
|
-
SSHKit::Coordinator.new(
|
54
|
+
subset_copy = Marshal.dump(Configuration.env.filter(hosts))
|
55
|
+
SSHKit::Coordinator.new(Marshal.load(subset_copy)).each(options, &block)
|
56
56
|
end
|
57
57
|
|
58
58
|
def run_locally(&block)
|
data/lib/capistrano/dsl/env.rb
CHANGED
@@ -47,8 +47,16 @@ module Capistrano
|
|
47
47
|
env.roles_for(names.flatten)
|
48
48
|
end
|
49
49
|
|
50
|
+
def role_properties(*names, &block)
|
51
|
+
env.role_properties_for(names, &block)
|
52
|
+
end
|
53
|
+
|
50
54
|
def release_roles(*names)
|
51
|
-
|
55
|
+
if names.last.is_a? Hash
|
56
|
+
names.last.merge!({ :exclude => :no_release })
|
57
|
+
else
|
58
|
+
names << { exclude: :no_release }
|
59
|
+
end
|
52
60
|
roles(*names)
|
53
61
|
end
|
54
62
|
|
data/lib/capistrano/dsl/paths.rb
CHANGED
data/lib/capistrano/git.rb
CHANGED
@@ -23,5 +23,5 @@ require 'capistrano/deploy'
|
|
23
23
|
# require 'capistrano/rails/migrations'
|
24
24
|
# require 'capistrano/passenger'
|
25
25
|
|
26
|
-
# Load custom tasks from `lib/capistrano/tasks
|
26
|
+
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
|
27
27
|
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
@@ -5,7 +5,7 @@ set :application, 'my_app_name'
|
|
5
5
|
set :repo_url, 'git@example.com:me/my_repo.git'
|
6
6
|
|
7
7
|
# Default branch is :master
|
8
|
-
# ask :branch,
|
8
|
+
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
|
9
9
|
|
10
10
|
# Default deploy_to directory is /var/www/my_app_name
|
11
11
|
# set :deploy_to, '/var/www/my_app_name'
|
@@ -23,10 +23,10 @@ set :repo_url, 'git@example.com:me/my_repo.git'
|
|
23
23
|
# set :pty, true
|
24
24
|
|
25
25
|
# Default value for :linked_files is []
|
26
|
-
# set :linked_files, fetch(:linked_files, []).push('config/database.yml')
|
26
|
+
# set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
|
27
27
|
|
28
28
|
# Default value for linked_dirs is []
|
29
|
-
# set :linked_dirs, fetch(:linked_dirs, []).push('
|
29
|
+
# set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
|
30
30
|
|
31
31
|
# Default value for default_env is {}
|
32
32
|
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
|
@@ -1,27 +1,43 @@
|
|
1
|
-
#
|
1
|
+
# server-based syntax
|
2
|
+
# ======================
|
3
|
+
# Defines a single server with a list of roles and multiple properties.
|
4
|
+
# You can define all roles on a single server, or split them:
|
5
|
+
|
6
|
+
# server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value
|
7
|
+
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
|
8
|
+
# server 'db.example.com', user: 'deploy', roles: %w{db}
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
# role-based syntax
|
2
13
|
# ==================
|
3
|
-
# Supports bulk-adding hosts to roles, the primary server in each group
|
4
|
-
# is considered to be the first unless any hosts have the primary
|
5
|
-
# property set. Don't declare `role :all`, it's a meta role.
|
6
14
|
|
7
|
-
role
|
8
|
-
|
9
|
-
|
15
|
+
# Defines a role with one or multiple servers. The primary server in each
|
16
|
+
# group is considered to be the first unless any hosts have the primary
|
17
|
+
# property set. Specify the username and a domain or IP for the server.
|
18
|
+
# Don't use `:all`, it's a meta role.
|
10
19
|
|
20
|
+
# role :app, %w{deploy@example.com}, my_property: :my_value
|
21
|
+
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
|
22
|
+
# role :db, %w{deploy@example.com}
|
11
23
|
|
12
|
-
# Extended Server Syntax
|
13
|
-
# ======================
|
14
|
-
# This can be used to drop a more detailed server definition into the
|
15
|
-
# server list. The second argument is a, or duck-types, Hash and is
|
16
|
-
# used to set extended properties on the server.
|
17
24
|
|
18
|
-
|
25
|
+
|
26
|
+
# Configuration
|
27
|
+
# =============
|
28
|
+
# You can set any configuration variable like in config/deploy.rb
|
29
|
+
# These variables are then only loaded and set in this stage.
|
30
|
+
# For available Capistrano configuration variables see the documentation page.
|
31
|
+
# http://capistranorb.com/documentation/getting-started/configuration/
|
32
|
+
# Feel free to add new variables to customise your setup.
|
33
|
+
|
19
34
|
|
20
35
|
|
21
36
|
# Custom SSH Options
|
22
37
|
# ==================
|
23
38
|
# You may pass any option but keep in mind that net/ssh understands a
|
24
|
-
# limited set of options, consult
|
39
|
+
# limited set of options, consult the Net::SSH documentation.
|
40
|
+
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
|
25
41
|
#
|
26
42
|
# Global options
|
27
43
|
# --------------
|
@@ -31,7 +47,7 @@ server 'example.com', user: 'deploy', roles: %w{web app}, my_property: :my_value
|
|
31
47
|
# auth_methods: %w(password)
|
32
48
|
# }
|
33
49
|
#
|
34
|
-
#
|
50
|
+
# The server-based syntax can be used to override options:
|
35
51
|
# ------------------------------------
|
36
52
|
# server 'example.com',
|
37
53
|
# user: 'user_name',
|
data/lib/capistrano/version.rb
CHANGED
@@ -15,7 +15,7 @@ describe Capistrano::DSL do
|
|
15
15
|
dsl.server 'example2.com', roles: %w{web}
|
16
16
|
dsl.server 'example3.com', roles: %w{app web}, active: true
|
17
17
|
dsl.server 'example4.com', roles: %w{app}, primary: true
|
18
|
-
dsl.server 'example5.com', roles: %w{db}, no_release: true
|
18
|
+
dsl.server 'example5.com', roles: %w{db}, no_release: true, active:true
|
19
19
|
end
|
20
20
|
|
21
21
|
describe 'fetching all servers' do
|
@@ -241,23 +241,43 @@ describe Capistrano::DSL do
|
|
241
241
|
end
|
242
242
|
|
243
243
|
describe 'fetching all servers' do
|
244
|
-
|
245
|
-
|
246
|
-
it 'creates a server instance for each unique user@host:port combination' do
|
247
|
-
expect(subject).to eq %w{db@example1.com:1234 root@example1.com:1234 @example1.com:5678 deployer@example1.com:1234}
|
244
|
+
it 'creates one server per hostname, ignoring user and port combinations' do
|
245
|
+
expect(dsl.roles(:all).size).to eq(1)
|
248
246
|
end
|
249
247
|
end
|
250
248
|
|
251
249
|
describe 'fetching servers for a role' do
|
252
250
|
it 'roles defined using the `server` syntax are included' do
|
253
|
-
|
251
|
+
as = dsl.roles(:web).map { |server| "#{server.user}@#{server.hostname}:#{server.port}" }
|
252
|
+
expect(as.size).to eq(1)
|
253
|
+
expect(as[0]).to eq("deployer@example1.com:5678")
|
254
254
|
end
|
255
255
|
|
256
256
|
it 'roles defined using the `role` syntax are included' do
|
257
|
-
|
257
|
+
as = dsl.roles(:app).map { |server| "#{server.user}@#{server.hostname}:#{server.port}" }
|
258
|
+
expect(as.size).to eq(1)
|
259
|
+
expect(as[0]).to eq("deployer@example1.com:5678")
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
describe 'when setting user and port' do
|
266
|
+
subject { dsl.roles(:all).map { |server| "#{server.user}@#{server.hostname}:#{server.port}" }.first }
|
267
|
+
|
268
|
+
describe "using the :user property" do
|
269
|
+
it "takes precedence over in the host string" do
|
270
|
+
dsl.server 'db@example1.com:1234', roles: %w{db}, active: true, user: 'brian'
|
271
|
+
expect(subject).to eq("brian@example1.com:1234")
|
258
272
|
end
|
259
273
|
end
|
260
274
|
|
275
|
+
describe "using the :port property" do
|
276
|
+
it "takes precedence over in the host string" do
|
277
|
+
dsl.server 'db@example1.com:9090', roles: %w{db}, active: true, port: 1234
|
278
|
+
expect(subject).to eq("db@example1.com:1234")
|
279
|
+
end
|
280
|
+
end
|
261
281
|
end
|
262
282
|
|
263
283
|
end
|
@@ -415,112 +435,6 @@ describe Capistrano::DSL do
|
|
415
435
|
|
416
436
|
end
|
417
437
|
|
418
|
-
describe 'release path' do
|
419
|
-
|
420
|
-
before do
|
421
|
-
dsl.set(:deploy_to, '/var/www')
|
422
|
-
end
|
423
|
-
|
424
|
-
describe 'fetching release path' do
|
425
|
-
subject { dsl.release_path }
|
426
|
-
|
427
|
-
context 'where no release path has been set' do
|
428
|
-
before do
|
429
|
-
dsl.delete(:release_path)
|
430
|
-
end
|
431
|
-
|
432
|
-
it 'returns the `current_path` value' do
|
433
|
-
expect(subject.to_s).to eq '/var/www/current'
|
434
|
-
end
|
435
|
-
end
|
436
|
-
|
437
|
-
context 'where the release path has been set' do
|
438
|
-
before do
|
439
|
-
dsl.set(:release_path, '/var/www/release_path')
|
440
|
-
end
|
441
|
-
|
442
|
-
it 'returns the set `release_path` value' do
|
443
|
-
expect(subject.to_s).to eq '/var/www/release_path'
|
444
|
-
end
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
describe 'setting release path' do
|
449
|
-
let(:now) { Time.parse("Oct 21 16:29:00 2015") }
|
450
|
-
subject { dsl.release_path }
|
451
|
-
|
452
|
-
context 'without a timestamp' do
|
453
|
-
before do
|
454
|
-
dsl.env.expects(:timestamp).returns(now)
|
455
|
-
dsl.set_release_path
|
456
|
-
end
|
457
|
-
|
458
|
-
it 'returns the release path with the current env timestamp' do
|
459
|
-
expect(subject.to_s).to eq '/var/www/releases/20151021162900'
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
context 'with a timestamp' do
|
464
|
-
before do
|
465
|
-
dsl.set_release_path('timestamp')
|
466
|
-
end
|
467
|
-
|
468
|
-
it 'returns the release path with the timestamp' do
|
469
|
-
expect(subject.to_s).to eq '/var/www/releases/timestamp'
|
470
|
-
end
|
471
|
-
end
|
472
|
-
end
|
473
|
-
|
474
|
-
describe 'setting deploy configuration path' do
|
475
|
-
subject { dsl.deploy_config_path.to_s }
|
476
|
-
|
477
|
-
context 'where no config path is set' do
|
478
|
-
before do
|
479
|
-
dsl.delete(:deploy_config_path)
|
480
|
-
end
|
481
|
-
|
482
|
-
it 'returns "config/deploy.rb"' do
|
483
|
-
expect(subject).to eq 'config/deploy.rb'
|
484
|
-
end
|
485
|
-
end
|
486
|
-
|
487
|
-
context 'where a custom path is set' do
|
488
|
-
before do
|
489
|
-
dsl.set(:deploy_config_path, 'my/custom/path.rb')
|
490
|
-
end
|
491
|
-
|
492
|
-
it 'returns the custom path' do
|
493
|
-
expect(subject).to eq 'my/custom/path.rb'
|
494
|
-
end
|
495
|
-
end
|
496
|
-
end
|
497
|
-
|
498
|
-
describe 'setting stage configuration path' do
|
499
|
-
subject { dsl.stage_config_path.to_s }
|
500
|
-
|
501
|
-
context 'where no config path is set' do
|
502
|
-
|
503
|
-
before do
|
504
|
-
dsl.delete(:stage_config_path)
|
505
|
-
end
|
506
|
-
|
507
|
-
it 'returns "config/deploy"' do
|
508
|
-
expect(subject).to eq 'config/deploy'
|
509
|
-
end
|
510
|
-
end
|
511
|
-
|
512
|
-
context 'where a custom path is set' do
|
513
|
-
before do
|
514
|
-
dsl.set(:stage_config_path, 'my/custom/path')
|
515
|
-
end
|
516
|
-
|
517
|
-
it 'returns the custom path' do
|
518
|
-
expect(subject).to eq 'my/custom/path'
|
519
|
-
end
|
520
|
-
end
|
521
|
-
end
|
522
|
-
end
|
523
|
-
|
524
438
|
describe 'local_user' do
|
525
439
|
before do
|
526
440
|
dsl.set :local_user, -> { Etc.getlogin }
|
@@ -607,4 +521,63 @@ describe Capistrano::DSL do
|
|
607
521
|
|
608
522
|
end
|
609
523
|
|
524
|
+
describe 'role_properties()' do
|
525
|
+
|
526
|
+
before do
|
527
|
+
dsl.role :redis, %w[example1.com example2.com], redis: { port: 6379, type: :slave }
|
528
|
+
dsl.server 'example1.com', roles: %w{web}, active: true, web: { port: 80 }
|
529
|
+
dsl.server 'example2.com', roles: %w{web redis}, web: { port: 81 }, redis: { type: :master }
|
530
|
+
dsl.server 'example3.com', roles: %w{app}, primary: true
|
531
|
+
end
|
532
|
+
|
533
|
+
it 'retrieves properties for a single role as a set' do
|
534
|
+
rps = dsl.role_properties(:app)
|
535
|
+
expect(rps).to eq(Set[{ hostname: 'example3.com', role: :app}])
|
536
|
+
end
|
537
|
+
|
538
|
+
it 'retrieves properties for multiple roles as a set' do
|
539
|
+
rps = dsl.role_properties(:app, :web)
|
540
|
+
expect(rps).to eq(Set[{ hostname: 'example3.com', role: :app},{ hostname: 'example1.com', role: :web, port: 80},{ hostname: 'example2.com', role: :web, port: 81}])
|
541
|
+
end
|
542
|
+
|
543
|
+
it 'yields the properties for a single role' do
|
544
|
+
recipient = mock('recipient')
|
545
|
+
recipient.expects(:doit).with('example1.com', :redis, { port: 6379, type: :slave})
|
546
|
+
recipient.expects(:doit).with('example2.com', :redis, { port: 6379, type: :master})
|
547
|
+
dsl.role_properties(:redis) do |host, role, props|
|
548
|
+
recipient.doit(host, role, props)
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
it 'yields the properties for multiple roles' do
|
553
|
+
recipient = mock('recipient')
|
554
|
+
recipient.expects(:doit).with('example1.com', :redis, { port: 6379, type: :slave})
|
555
|
+
recipient.expects(:doit).with('example2.com', :redis, { port: 6379, type: :master})
|
556
|
+
recipient.expects(:doit).with('example3.com', :app, nil)
|
557
|
+
dsl.role_properties(:redis, :app) do |host, role, props|
|
558
|
+
recipient.doit(host, role, props)
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
it 'yields the merged properties for multiple roles' do
|
563
|
+
recipient = mock('recipient')
|
564
|
+
recipient.expects(:doit).with('example1.com', :redis, { port: 6379, type: :slave})
|
565
|
+
recipient.expects(:doit).with('example2.com', :redis, { port: 6379, type: :master})
|
566
|
+
recipient.expects(:doit).with('example1.com', :web, { port: 80 })
|
567
|
+
recipient.expects(:doit).with('example2.com', :web, { port: 81 })
|
568
|
+
dsl.role_properties(:redis, :web) do |host, role, props|
|
569
|
+
recipient.doit(host, role, props)
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
it 'honours a property filter before yielding' do
|
574
|
+
recipient = mock('recipient')
|
575
|
+
recipient.expects(:doit).with('example1.com', :redis, { port: 6379, type: :slave})
|
576
|
+
recipient.expects(:doit).with('example1.com', :web, { port: 80 })
|
577
|
+
dsl.role_properties(:redis, :web, select: :active) do |host, role, props|
|
578
|
+
recipient.doit(host, role, props)
|
579
|
+
end
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
610
583
|
end
|