beaker 1.3.2 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/beaker/dsl/helpers.rb +12 -2
- data/lib/beaker/dsl/install_utils.rb +43 -5
- data/lib/beaker/host.rb +16 -7
- data/lib/beaker/options/command_line_parser.rb +1 -1
- data/lib/beaker/options/parser.rb +2 -2
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/dsl/helpers_spec.rb +19 -0
- data/spec/beaker/dsl/install_utils_spec.rb +64 -1
- data/spec/beaker/host_spec.rb +8 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZmRmOTdmNmVlZDNkMjFiMGIyNTAzZTRjYjRiMDRmYWU5Mjk3NDZmMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjY1MWEyOGQyMzdjNDZjM2Q0YWNmMzY0N2U3ZTE4ZGQ4NThmMWExNw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTk5MWY3N2NjNWI5ZDMwNjZiMzM4YWRlNmUwMDczYTY3ZTFhNDc1MzViYzEz
|
10
|
+
NjZkZDBkZjczMWEwZWNjOTEyN2E1ZTk1N2YxNDFlMzhlOWVjMzE4ZjhmOTVj
|
11
|
+
OTlkODM2Y2Y0NWViYjA4ZWE3YzA0M2RhYzExZGRiOTI0MDZjMzQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NWRlNmUxNzM0Y2E3MDYwNmNjODZhYzk1YzQ1NDdjMTA2NWQ5ZTdjMjAzODVj
|
14
|
+
ZjdlYzg4NjI5MDFjMTU2MjRjYTNkZWNhZDVkZWIzNDc1MmRhZGQwMDVlZmIx
|
15
|
+
OGY1OTdkZDdhZTk2OWJlOGNiZTM0MGIyMzViZTVhMzg4NTFhZTM=
|
data/lib/beaker/dsl/helpers.rb
CHANGED
@@ -659,6 +659,11 @@ module Beaker
|
|
659
659
|
# if `puppet --apply` indicates that there were
|
660
660
|
# changes or failures during its execution.
|
661
661
|
#
|
662
|
+
# @option opts [Boolean] :expect_changes (false) This option enables
|
663
|
+
# detailed exit codes and causes a test failure
|
664
|
+
# if `puppet --apply` indicates that there were
|
665
|
+
# no resource changes during its execution.
|
666
|
+
#
|
662
667
|
# @option opts [Boolean] :expect_failures (false) This option enables
|
663
668
|
# detailed exit codes and causes a test failure
|
664
669
|
# if `puppet --apply` indicates there were no
|
@@ -679,8 +684,8 @@ module Beaker
|
|
679
684
|
# "... an exit code of '2' means there were changes, an exit code of
|
680
685
|
# '4' means there were failures during the transaction, and an exit
|
681
686
|
# code of '6' means there were both changes and failures."
|
682
|
-
if [opts[:catch_changes],opts[:catch_failures],opts[:expect_failures]].select{|x|x}.length > 1
|
683
|
-
raise(ArgumentError, "Cannot specify more than one of `catch_failures`, `catch_changes`, or `
|
687
|
+
if [opts[:catch_changes],opts[:catch_failures],opts[:expect_failures],opts[:expect_changes]].select{|x|x}.length > 1
|
688
|
+
raise(ArgumentError, "Cannot specify more than one of `catch_failures`, `catch_changes`, `expect_failures`, or `expect_changes` for a single manifest")
|
684
689
|
end
|
685
690
|
if opts[:catch_changes]
|
686
691
|
args << '--detailed-exitcodes'
|
@@ -697,6 +702,11 @@ module Beaker
|
|
697
702
|
|
698
703
|
# We're after failures specifically so allow exit codes 1, 4, and 6 only.
|
699
704
|
on_options[:acceptable_exit_codes] |= [1, 4, 6]
|
705
|
+
elsif opts[:expect_changes]
|
706
|
+
args << '--detailed-exitcodes'
|
707
|
+
|
708
|
+
# We're after changes specifically so allow exit code 2 only.
|
709
|
+
on_options[:acceptable_exit_codes] |= [2]
|
700
710
|
else
|
701
711
|
# Either use the provided acceptable_exit_codes or default to [0]
|
702
712
|
on_options[:acceptable_exit_codes] |= [0]
|
@@ -141,12 +141,14 @@ module Beaker
|
|
141
141
|
# on host, "#{installer_cmd(host, options)} -a #{host['working_dir']}/answers"
|
142
142
|
# @api private
|
143
143
|
def installer_cmd(host, options)
|
144
|
+
version = options[:pe_ver] || host['pe_ver']
|
144
145
|
if host['platform'] =~ /windows/
|
145
146
|
version = options[:pe_ver_win] || host['pe_ver']
|
146
147
|
"cd #{host['working_dir']} && msiexec.exe /qn /i puppet-enterprise-#{version}.msi"
|
147
|
-
|
148
|
-
|
149
|
-
|
148
|
+
# Frictionless install didn't exist pre-3.2.0, so in that case we fall
|
149
|
+
# through and do a regular install.
|
150
|
+
elsif host['roles'].include? 'frictionless' and ! version_is_less(version, '3.2.0')
|
151
|
+
"cd #{host['working_dir']} && curl -kO https://#{master}:8140/packages/#{version}/install.bash && bash install.bash"
|
150
152
|
else
|
151
153
|
"cd #{host['working_dir']}/#{host['dist']} && ./#{options[:installer]} -a #{host['working_dir']}/answers"
|
152
154
|
end
|
@@ -184,7 +186,7 @@ module Beaker
|
|
184
186
|
def fetch_puppet(hosts, options)
|
185
187
|
hosts.each do |host|
|
186
188
|
# We install Puppet from the master for frictionless installs, so we don't need to *fetch* anything
|
187
|
-
next if host['roles'].include? 'frictionless'
|
189
|
+
next if host['roles'].include? 'frictionless' and ! version_is_less(options[:pe_ver] || host['pe_ver'], '3.2.0')
|
188
190
|
|
189
191
|
windows = host['platform'] =~ /windows/
|
190
192
|
path = options[:pe_dir] || host['pe_dir']
|
@@ -279,7 +281,8 @@ module Beaker
|
|
279
281
|
on host, "#{installer_cmd(host, options)} PUPPET_MASTER_SERVER=#{master} PUPPET_AGENT_CERTNAME=#{host}"
|
280
282
|
else
|
281
283
|
# We only need answers if we're using the classic installer
|
282
|
-
|
284
|
+
version = options[:pe_ver] || host['pe_ver']
|
285
|
+
if (! host['roles'].include? 'frictionless') || version_is_less(version, '3.2.0')
|
283
286
|
answers = Beaker::Answers.answers(options[:pe_ver] || host['pe_ver'], hosts, master_certname, options)
|
284
287
|
create_remote_file host, "#{host['working_dir']}/answers", Beaker::Answers.answer_string(host, answers)
|
285
288
|
end
|
@@ -383,6 +386,41 @@ module Beaker
|
|
383
386
|
special_nodes + real_agents
|
384
387
|
end
|
385
388
|
|
389
|
+
#Install POSS based upon host configuration and options
|
390
|
+
# @example
|
391
|
+
# install_puppet
|
392
|
+
#
|
393
|
+
# @note This will attempt to add a repository for apt.puppetlabs.com on
|
394
|
+
# Debian or Ubuntu machines, or yum.puppetlabs.com on EL or Fedora
|
395
|
+
# machines, then install the package 'puppet'
|
396
|
+
#
|
397
|
+
# @api dsl
|
398
|
+
# @return nil
|
399
|
+
def install_puppet
|
400
|
+
hosts.each do |host|
|
401
|
+
if host['platform'] =~ /el-(5|6)/
|
402
|
+
relver = $1
|
403
|
+
on host, "rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-#{relver}.noarch.rpm"
|
404
|
+
on host, 'yum install -y puppet'
|
405
|
+
elsif host['platform'] =~ /fedora-(\d+)/
|
406
|
+
relver = $1
|
407
|
+
on host, "rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-fedora-#{relver}.noarch.rpm"
|
408
|
+
on host, 'yum install -y puppet'
|
409
|
+
elsif host['platform'] =~ /(ubuntu|debian)/
|
410
|
+
if ! host.check_for_package 'curl'
|
411
|
+
on host, 'apt-get install -y curl'
|
412
|
+
end
|
413
|
+
on host, 'curl -O http://apt.puppetlabs.com/puppetlabs-release-$(lsb_release -c -s).deb'
|
414
|
+
on host, 'dpkg -i puppetlabs-release-$(lsb_release -c -s).deb'
|
415
|
+
on host, 'apt-get -y -f -m update'
|
416
|
+
on host, 'apt-get install -y puppet'
|
417
|
+
else
|
418
|
+
raise "install_puppet() called for unsupported platform '#{host['platform']}' on '#{host.name}'"
|
419
|
+
end
|
420
|
+
end
|
421
|
+
nil
|
422
|
+
end
|
423
|
+
|
386
424
|
#Install PE based upon host configuration and options
|
387
425
|
# @example
|
388
426
|
# install_pe
|
data/lib/beaker/host.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'timeout'
|
3
|
+
require 'benchmark'
|
3
4
|
|
4
5
|
%w(command ssh_connection).each do |lib|
|
5
6
|
begin
|
@@ -131,6 +132,14 @@ module Beaker
|
|
131
132
|
@options.is_pe?
|
132
133
|
end
|
133
134
|
|
135
|
+
def log_prefix
|
136
|
+
if @defaults['vmhostname']
|
137
|
+
"#{self} (#{@name})"
|
138
|
+
else
|
139
|
+
self.to_s
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
134
143
|
def connection
|
135
144
|
@connection ||= SshConnection.connect( reachable_name,
|
136
145
|
self['user'],
|
@@ -149,11 +158,7 @@ module Beaker
|
|
149
158
|
if options[:silent]
|
150
159
|
output_callback = nil
|
151
160
|
else
|
152
|
-
|
153
|
-
@logger.debug "\n#{self} (#{@name}) $ #{cmdline}"
|
154
|
-
else
|
155
|
-
@logger.debug "\n#{self} $ #{cmdline}"
|
156
|
-
end
|
161
|
+
@logger.debug "\n#{log_prefix} $ #{cmdline}"
|
157
162
|
output_callback = logger.method(:host_output)
|
158
163
|
end
|
159
164
|
|
@@ -161,7 +166,12 @@ module Beaker
|
|
161
166
|
# is this returning a result object?
|
162
167
|
# the options should come at the end of the method signature (rubyism)
|
163
168
|
# and they shouldn't be ssh specific
|
164
|
-
result =
|
169
|
+
result = nil
|
170
|
+
|
171
|
+
seconds = Benchmark.realtime {
|
172
|
+
result = connection.execute(cmdline, options, output_callback)
|
173
|
+
}
|
174
|
+
@logger.debug "\n#{log_prefix} executed in %0.2f seconds" % seconds
|
165
175
|
|
166
176
|
unless options[:silent]
|
167
177
|
# What?
|
@@ -180,7 +190,6 @@ module Beaker
|
|
180
190
|
end
|
181
191
|
|
182
192
|
def do_scp_to source, target, options
|
183
|
-
|
184
193
|
@logger.debug "localhost $ scp #{source} #{@name}:#{target} #{options.to_s}"
|
185
194
|
result = connection.scp_to(source, target, options, $dry_run)
|
186
195
|
return result
|
@@ -234,8 +234,8 @@ module Beaker
|
|
234
234
|
end
|
235
235
|
|
236
236
|
#check for valid type
|
237
|
-
if @options[:type] !~ /(pe)|(git)/
|
238
|
-
parser_error "--type must be one of pe or
|
237
|
+
if @options[:type] !~ /(pe)|(git)|(foss)/
|
238
|
+
parser_error "--type must be one of pe, git, or foss, not '#{@options[:type]}'"
|
239
239
|
end
|
240
240
|
|
241
241
|
#check for valid fail mode
|
data/lib/beaker/version.rb
CHANGED
@@ -359,6 +359,25 @@ describe ClassMixedWithDSLHelpers do
|
|
359
359
|
:catch_changes => true
|
360
360
|
)
|
361
361
|
end
|
362
|
+
it 'enforces a 2 exit code through :expect_changes' do
|
363
|
+
subject.should_receive( :create_remote_file ).and_return( true )
|
364
|
+
subject.should_receive( :puppet ).
|
365
|
+
with( 'apply', '--verbose', '--trace', '--detailed-exitcodes', /apply_manifest.\d+.pp/ ).
|
366
|
+
and_return( 'puppet_command' )
|
367
|
+
|
368
|
+
subject.should_receive( :on ).with(
|
369
|
+
'my_host',
|
370
|
+
'puppet_command',
|
371
|
+
:acceptable_exit_codes => [2]
|
372
|
+
)
|
373
|
+
|
374
|
+
subject.apply_manifest_on(
|
375
|
+
'my_host',
|
376
|
+
'class { "boo": }',
|
377
|
+
:trace => true,
|
378
|
+
:expect_changes => true
|
379
|
+
)
|
380
|
+
end
|
362
381
|
it 'enforces exit codes through :expect_failures' do
|
363
382
|
subject.should_receive( :create_remote_file ).and_return( true )
|
364
383
|
subject.should_receive( :puppet ).
|
@@ -197,8 +197,9 @@ describe ClassMixedWithDSLInstallUtils do
|
|
197
197
|
|
198
198
|
end
|
199
199
|
|
200
|
-
it "does nothing for a frictionless agent" do
|
200
|
+
it "does nothing for a frictionless agent for PE >= 3.2.0" do
|
201
201
|
unixhost['roles'] << 'frictionless'
|
202
|
+
unixhost['pe_ver'] = '3.2.0'
|
202
203
|
|
203
204
|
subject.should_not_receive(:scp_to)
|
204
205
|
subject.should_not_receive(:on)
|
@@ -257,6 +258,68 @@ describe ClassMixedWithDSLInstallUtils do
|
|
257
258
|
end
|
258
259
|
end
|
259
260
|
|
261
|
+
describe '#install_puppet' do
|
262
|
+
let(:hosts) do
|
263
|
+
make_hosts({:platform => platform })
|
264
|
+
end
|
265
|
+
|
266
|
+
before do
|
267
|
+
subject.stub(:hosts).and_return(hosts)
|
268
|
+
subject.stub(:on).and_return(Beaker::Result.new({},''))
|
269
|
+
end
|
270
|
+
context 'on el-6' do
|
271
|
+
let(:platform) { "el-6-i386" }
|
272
|
+
it 'installs' do
|
273
|
+
expect(subject).to receive(:on).with(hosts[0], /puppetlabs-release-el-6\.noarch\.rpm/)
|
274
|
+
expect(subject).to receive(:on).with(hosts[0], 'yum install -y puppet')
|
275
|
+
subject.install_puppet
|
276
|
+
end
|
277
|
+
end
|
278
|
+
context 'on el-5' do
|
279
|
+
let(:platform) { "el-5-i386" }
|
280
|
+
it 'installs' do
|
281
|
+
expect(subject).to receive(:on).with(hosts[0], /puppetlabs-release-el-5\.noarch\.rpm/)
|
282
|
+
expect(subject).to receive(:on).with(hosts[0], 'yum install -y puppet')
|
283
|
+
subject.install_puppet
|
284
|
+
end
|
285
|
+
end
|
286
|
+
context 'on fedora' do
|
287
|
+
let(:platform) { "fedora-18-x86_84" }
|
288
|
+
it 'installs' do
|
289
|
+
expect(subject).to receive(:on).with(hosts[0], /puppetlabs-release-fedora-18\.noarch\.rpm/)
|
290
|
+
expect(subject).to receive(:on).with(hosts[0], 'yum install -y puppet')
|
291
|
+
subject.install_puppet
|
292
|
+
end
|
293
|
+
end
|
294
|
+
context 'on debian' do
|
295
|
+
let(:platform) { "debian-7-amd64" }
|
296
|
+
it 'installs' do
|
297
|
+
expect(subject).to receive(:on).with(hosts[0], /puppetlabs-release-\$\(lsb_release -c -s\)\.deb/)
|
298
|
+
expect(subject).to receive(:on).with(hosts[0], 'dpkg -i puppetlabs-release-$(lsb_release -c -s).deb')
|
299
|
+
expect(subject).to receive(:on).with(hosts[0], 'apt-get -y -f -m update')
|
300
|
+
expect(subject).to receive(:on).with(hosts[0], 'apt-get install -y puppet')
|
301
|
+
subject.install_puppet
|
302
|
+
end
|
303
|
+
end
|
304
|
+
context 'on ubuntu' do
|
305
|
+
let(:platform) { "ubuntu-12.04-amd64" }
|
306
|
+
it 'installs' do
|
307
|
+
expect(subject).to receive(:on).with(hosts[0], /puppetlabs-release-\$\(lsb_release -c -s\)\.deb/)
|
308
|
+
expect(subject).to receive(:on).with(hosts[0], 'dpkg -i puppetlabs-release-$(lsb_release -c -s).deb')
|
309
|
+
expect(subject).to receive(:on).with(hosts[0], 'apt-get -y -f -m update')
|
310
|
+
expect(subject).to receive(:on).with(hosts[0], 'apt-get install -y puppet')
|
311
|
+
subject.install_puppet
|
312
|
+
end
|
313
|
+
end
|
314
|
+
context 'on solaris' do
|
315
|
+
let(:platform) { 'solaris-11-x86_64' }
|
316
|
+
it 'raises an error' do
|
317
|
+
expect(subject).to_not receive(:on)
|
318
|
+
expect { subject.install_puppet }.to raise_error(/unsupported platform/)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
260
323
|
describe 'install_pe' do
|
261
324
|
|
262
325
|
it 'calls do_install with sorted hosts' do
|
data/spec/beaker/host_spec.rb
CHANGED
@@ -112,6 +112,14 @@ module Beaker
|
|
112
112
|
it 'receives a result object from the connection#execute'
|
113
113
|
it "returns the result object"
|
114
114
|
|
115
|
+
it 'logs the amount of time spent executing the command' do
|
116
|
+
result.exit_code = 0
|
117
|
+
|
118
|
+
expect(host.logger).to receive(:debug).with(/host executed in \d\.\d{2} seconds/)
|
119
|
+
|
120
|
+
host.exec(command,{})
|
121
|
+
end
|
122
|
+
|
115
123
|
context "controls the result objects logging" do
|
116
124
|
it "and passes a test if the exit_code doesn't match the default :acceptable_exit_codes of 0" do
|
117
125
|
result.exit_code = 0
|