beaker 3.18.0 → 3.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +8 -8
  2. data/Rakefile +0 -23
  3. data/beaker.gemspec +1 -0
  4. data/lib/beaker/dsl/helpers.rb +3 -4
  5. data/lib/beaker/dsl/install_utils.rb +2 -7
  6. data/lib/beaker/dsl/wrappers.rb +0 -87
  7. data/lib/beaker/host/unix/pkg.rb +56 -17
  8. data/lib/beaker/hypervisor/docker.rb +26 -1
  9. data/lib/beaker/options/parser.rb +12 -5
  10. data/lib/beaker/options/subcommand_options_file_parser.rb +11 -4
  11. data/lib/beaker/ssh_connection.rb +6 -6
  12. data/lib/beaker/subcommand.rb +6 -0
  13. data/lib/beaker/version.rb +1 -1
  14. data/spec/beaker/host/unix/pkg_spec.rb +130 -0
  15. data/spec/beaker/hypervisor/docker_spec.rb +28 -1
  16. data/spec/beaker/options/parser_spec.rb +38 -18
  17. data/spec/beaker/options/subcommand_options_parser_spec.rb +28 -5
  18. data/spec/beaker/ssh_connection_spec.rb +17 -17
  19. metadata +16 -28
  20. data/acceptance/config/puppetgem/acceptance-options.rb +0 -9
  21. data/acceptance/config/puppetgit/acceptance-options.rb +0 -9
  22. data/acceptance/config/puppetpkg/acceptance-options.rb +0 -8
  23. data/acceptance/pre_suite/puppet_gem/install.rb +0 -8
  24. data/acceptance/pre_suite/puppet_git/install.rb +0 -98
  25. data/acceptance/pre_suite/puppet_pkg/install.rb +0 -9
  26. data/acceptance/tests/puppet/README.md +0 -3
  27. data/acceptance/tests/puppet/install_smoke_test.rb +0 -21
  28. data/acceptance/tests/puppet/stub_host.rb +0 -47
  29. data/acceptance/tests/puppet/web_helpers_test.rb +0 -55
  30. data/acceptance/tests/puppet/with_puppet_running_on.rb +0 -26
  31. data/lib/beaker/dsl/helpers/puppet_helpers.rb +0 -865
  32. data/lib/beaker/dsl/helpers/tk_helpers.rb +0 -89
  33. data/lib/beaker/dsl/install_utils/aio_defaults.rb +0 -93
  34. data/lib/beaker/dsl/install_utils/ezbake_utils.rb +0 -256
  35. data/lib/beaker/dsl/install_utils/foss_defaults.rb +0 -211
  36. data/lib/beaker/dsl/install_utils/foss_utils.rb +0 -1307
  37. data/lib/beaker/dsl/install_utils/module_utils.rb +0 -244
  38. data/lib/beaker/dsl/install_utils/puppet_utils.rb +0 -157
  39. data/lib/beaker/options/homedir_options_file_parser.rb +0 -0
  40. data/spec/beaker/dsl/helpers/facter_helpers_spec.rb +0 -59
  41. data/spec/beaker/dsl/helpers/puppet_helpers_spec.rb +0 -1179
  42. data/spec/beaker/dsl/helpers/tk_helpers_spec.rb +0 -83
  43. data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +0 -1307
  44. data/spec/beaker/dsl/install_utils/module_utils_spec.rb +0 -261
  45. data/spec/beaker/dsl/install_utils/puppet_utils_spec.rb +0 -136
@@ -1,9 +0,0 @@
1
- {
2
- :type => 'foss',
3
- :add_el_extras => 'true',
4
- :is_puppetserver => false,
5
- :puppetservice => 'puppet.service',
6
- :pre_suite => 'acceptance/pre_suite/puppet_gem/install.rb',
7
- :tests => 'acceptance/tests/puppet',
8
- :'master-start-curl-retries' => 30,
9
- }.merge(eval File.read('acceptance/config/acceptance-options.rb'))
@@ -1,9 +0,0 @@
1
- {
2
- :type => 'foss',
3
- :add_el_extras => 'true',
4
- :is_puppetserver => false,
5
- :puppetservice => 'puppet.service',
6
- :pre_suite => 'acceptance/pre_suite/puppet_git/install.rb',
7
- :tests => 'acceptance/tests/puppet',
8
- :'master-start-curl-retries' => 30,
9
- }.merge(eval File.read('acceptance/config/acceptance-options.rb'))
@@ -1,8 +0,0 @@
1
- {
2
- :type => 'foss',
3
- :is_puppetserver => false,
4
- :puppetservice => 'puppet.service',
5
- :pre_suite => 'acceptance/pre_suite/puppet_pkg/install.rb',
6
- :tests => 'acceptance/tests/puppet',
7
- :'master-start-curl-retries' => 30,
8
- }.merge(eval File.read('acceptance/config/acceptance-options.rb'))
@@ -1,8 +0,0 @@
1
- hosts.each do |host|
2
- install_puppet_from_gem(host, {:version => '3.8.7'})
3
- unless host['platform'] =~ /windows/
4
- on(host, "touch #{File.join(host.puppet['confdir'],'puppet.conf')}")
5
- on(host, puppet('resource user puppet ensure=present'))
6
- on(host, puppet('resource group puppet ensure=present'))
7
- end
8
- end
@@ -1,98 +0,0 @@
1
- begin
2
- $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
3
- require 'beaker/acceptance/install_utils'
4
- extend Beaker::Acceptance::InstallUtils
5
- end
6
- test_name 'Puppet git pre-suite'
7
-
8
- install = [
9
- 'facter#2.1.0',
10
- 'hiera#1.3.4',
11
- 'puppet#3.8.7'
12
- ]
13
-
14
- SourcePath = Beaker::DSL::InstallUtils::SourcePath
15
-
16
- PACKAGES = {
17
- :redhat => [
18
- 'git',
19
- 'ruby',
20
- 'rubygem-json', # :add_el_extras is required to find this package
21
- ],
22
- :debian => [
23
- ['git', 'git-core'],
24
- 'ruby',
25
- ],
26
- :debian_ruby18 => [
27
- 'libjson-ruby',
28
- ],
29
- :solaris_11 => [
30
- ['git', 'developer/versioning/git'],
31
- ['ruby', 'runtime/ruby-18'],
32
- ],
33
- :solaris_10 => [
34
- 'coreutils',
35
- 'curl', # update curl to fix "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!" issue
36
- 'git',
37
- 'ruby19',
38
- 'ruby19_dev',
39
- 'gcc4core',
40
- ],
41
- :windows => [
42
- 'git',
43
- # there isn't a need for json on windows because it is bundled in ruby 1.9
44
- ],
45
- :sles => [
46
- 'git-core',
47
- ]
48
- }
49
-
50
- install_packages_on(hosts, PACKAGES, :check_if_exists => true)
51
-
52
- hosts.each do |host|
53
- case host['platform']
54
- when /windows/
55
- arch = host[:ruby_arch] || 'x86'
56
- step "#{host} Selected architecture #{arch}"
57
-
58
- revision = if arch == 'x64'
59
- '2.1.x-x64'
60
- else
61
- '2.1.x-x86'
62
- end
63
-
64
- step "#{host} Install ruby from git using revision #{revision}"
65
- # TODO remove this step once we are installing puppet from msi packages
66
- install_from_git(host, "/opt/puppet-git-repos",
67
- :name => 'puppet-win32-ruby',
68
- :path => build_giturl('puppet-win32-ruby'),
69
- :rev => revision)
70
- on host, 'cd /opt/puppet-git-repos/puppet-win32-ruby; cp -r ruby/* /'
71
- on host, 'cd /lib; icacls ruby /grant "Everyone:(OI)(CI)(RX)"'
72
- on host, 'cd /lib; icacls ruby /reset /T'
73
- on host, 'cd /; icacls bin /grant "Everyone:(OI)(CI)(RX)"'
74
- on host, 'cd /; icacls bin /reset /T'
75
- on host, 'ruby --version'
76
- on host, 'cmd /c gem list'
77
- when /solaris/
78
- on host, 'gem install json'
79
- end
80
- end
81
-
82
- tmp_repos = []
83
- install.each do |reponame|
84
- tmp_repos << extract_repo_info_from("https://github.com/puppetlabs/#{reponame}")
85
- end
86
-
87
- repos = order_packages(tmp_repos)
88
-
89
- hosts.each do |host|
90
- repos.each do |repo|
91
- install_from_git(host, SourcePath, repo)
92
- end
93
- unless host['platform'] =~ /windows/
94
- on(host, "touch #{File.join(host.puppet['confdir'],'puppet.conf')}")
95
- on(host, puppet('resource user puppet ensure=present'))
96
- on(host, puppet('resource group puppet ensure=present'))
97
- end
98
- end
@@ -1,9 +0,0 @@
1
- # the version is required on windows
2
- # all versions are required for osx
3
- install_puppet({
4
- :version => ENV['BEAKER_PUPPET_VERSION'] || '4.8.0',
5
- :puppet_agent_version => ENV['BEAKER_PUPPET_AGENT_VERSION'] || '1.8.0'
6
- })
7
-
8
- on(master, puppet('resource user puppet ensure=present'))
9
- on(master, puppet('resource group puppet ensure=present'))
@@ -1,3 +0,0 @@
1
- # Beaker Acceptance Tests: puppet
2
-
3
- Tests that depend upon Puppet being installed on the SUTs.
@@ -1,21 +0,0 @@
1
- test_name "puppet install smoketest"
2
-
3
- step 'puppet install smoketest: verify \'facter --help\' can be successfully called on all hosts'
4
- hosts.each do |host|
5
- on host, facter('--help')
6
- end
7
-
8
- step 'puppet install smoketest: verify \'hiera --help\' can be successfully called on all hosts'
9
- hosts.each do |host|
10
- on host, hiera('--help')
11
- end
12
-
13
- step 'puppet install smoketest: verify \'puppet help\' can be successfully called on all hosts'
14
- hosts.each do |host|
15
- on host, puppet('help')
16
- end
17
-
18
- step "puppet install smoketest: can get a configprint of the puppet server setting on all hosts"
19
- hosts.each do |host|
20
- assert(!host.puppet['server'].empty?, "can get a configprint of the puppet server setting")
21
- end
@@ -1,47 +0,0 @@
1
- test_name "validate host stubbing behavior"
2
-
3
- def get_hosts_file(host)
4
- if host['platform'] =~ /win/
5
- hosts_file = "C:\\\\Windows\\\\System32\\\\Drivers\\\\etc\\\\hosts"
6
- else
7
- hosts_file = '/etc/hosts'
8
- end
9
- return hosts_file
10
- end
11
-
12
- step 'verify stub_host_on' do
13
- step 'should add entry to hosts file' do
14
- hosts.each do |host|
15
- stub_hosts_on(host, { 'foo' => '1.1.1.1' }, { 'foo' => [ 'bar', 'baz' ] })
16
- hosts_file = get_hosts_file(host)
17
- result = on host, "cat #{hosts_file}"
18
- assert_match %r{foo}, result.stdout
19
- end
20
- end
21
-
22
- step 'stubbed value should be available for other steps in the test' do
23
- hosts.each do |host|
24
- hosts_file = get_hosts_file(host)
25
- result = on host, "cat #{hosts_file}"
26
- assert_match %r{foo}, result.stdout
27
- end
28
- end
29
- end
30
-
31
- step 'verify with_stub_host_on' do
32
- step 'should add entry to hosts file' do
33
- hosts.each do |host|
34
- hosts_file = get_hosts_file(host)
35
- result = with_host_stubbed_on(host, { 'sleepy' => '1.1.1.2' }, { 'sleepy' => [ 'grumpy', 'dopey' ] }) { on host, "cat #{hosts_file}" }
36
- assert_match %r{sleepy}, result.stdout
37
- end
38
- end
39
-
40
- step 'stubbed value should be reverted after the execution of the block' do
41
- hosts.each do |host|
42
- hosts_file = get_hosts_file(host)
43
- result = on host, "cat #{hosts_file}"
44
- assert_no_match %r{sleepy}, result.stdout
45
- end
46
- end
47
- end
@@ -1,55 +0,0 @@
1
- require 'helpers/test_helper'
2
- require 'webrick'
3
- require 'webrick/https'
4
-
5
- test_name 'dsl::helpers::web_helpers #link_exists?' do
6
- cert_name = [
7
- %w[CN localhost],
8
- ]
9
- http_cmd = "ruby -rwebrick -e'WEBrick::HTTPServer.new(:Port => 80, :DocumentRoot => \"/tmp\").start' > /tmp/mylogfile 2>&1 &"
10
- https_cmd = "ruby -rwebrick/https -e'WEBrick::HTTPServer.new(:SSLEnable => true, :SSLCertName => #{cert_name}, :Port => 555,:DocumentRoot => \"/tmp\").start' > /tmp/mylogfile 2>&1 &"
11
- on(default, http_cmd)
12
- on(default, https_cmd)
13
- #allow web servers to start up
14
- sleep(3)
15
- dir = default.tmpdir('test_dir')
16
- file = default.tmpfile('test_file')
17
- dir.slice! "/tmp"
18
- file.slice! "/tmp"
19
- dst_dir = 'web_helpers'
20
-
21
- step '#port_open_within? can tell if a port is open' do
22
- assert port_open_within?(default,80)
23
- end
24
-
25
- step '#link_exists? can tell if a basic link exists' do
26
- assert link_exists?("http://#{default}")
27
- end
28
-
29
- step '#link_exists? can tell if a basic link does not exist' do
30
- assert !link_exists?("http://#{default}/test")
31
- end
32
-
33
- step '#link_exists? can use an ssl link' do
34
- assert link_exists?("https://#{default}:555")
35
- end
36
-
37
- step '#fetch_http_dir can fetch a dir' do
38
- assert_equal "#{dst_dir}#{dir}", fetch_http_dir("http://#{default}/#{dir}", dst_dir)
39
- end
40
-
41
- step '#fetch_http_dir will raise an error if unable fetch a dir' do
42
- exception = assert_raises(RuntimeError) { fetch_http_dir("http://#{default}/tmps", dst_dir) }
43
- assert_match /Failed to fetch_remote_dir.*/, exception.message, "#fetch_http_dir raised an unexpected RuntimeError"
44
- end
45
-
46
- step '#fetch_http_file can fetch a file' do
47
- assert_equal "#{dst_dir}#{file}", fetch_http_file("http://#{default}", file, dst_dir)
48
- end
49
-
50
- step '#fetch_http_file will raise an error if unable to fetch a file' do
51
- exception = assert_raises(RuntimeError) { fetch_http_file("http://#{default}", "test2.txt", dst_dir) }
52
- assert_match /Failed to fetch_remote_file.*/, exception.message, "#fetch_http_dir raised an unexpected RuntimeError"
53
- end
54
-
55
- end
@@ -1,26 +0,0 @@
1
- test_name 'skip_test in with_puppet_running_on' do
2
- assert_raises SkipTest do
3
- with_puppet_running_on(master, {}) do
4
- skip_test 'skip rest'
5
- assert(false)
6
- end
7
- end
8
- end
9
-
10
- test_name 'pending_test in with_puppet_running_on' do
11
- assert_raises PendingTest do
12
- with_puppet_running_on(master, {}) do
13
- pending_test 'pending appendix prepended'
14
- assert(false)
15
- end
16
- end
17
- end
18
-
19
- test_name 'fail_test in with_puppet_running_on' do
20
- assert_raises FailTest do
21
- with_puppet_running_on(master, {}) do
22
- fail_test 'fail_test message'
23
- assert(false)
24
- end
25
- end
26
- end
@@ -1,865 +0,0 @@
1
- require 'timeout'
2
- require 'inifile'
3
- require 'resolv'
4
-
5
- module Beaker
6
- module DSL
7
- module Helpers
8
- # Methods that help you interact with your puppet installation, puppet must be installed
9
- # for these methods to execute correctly
10
- module PuppetHelpers
11
-
12
- # Return the regular expression pattern for an IPv4 address
13
- def ipv4_regex
14
- return /(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/
15
- end
16
-
17
- # Return the IP address that given hostname returns when resolved on
18
- # the given host.
19
- #
20
- # @ param [Host] host One object that acts like a Beaker::Host
21
- # @ param [String] hostname The hostname to perform a DNS resolution on
22
- #
23
- # @return [String, nil] An IP address, or nil.
24
- def resolve_hostname_on(host, hostname)
25
- match = curl_on(host, "--verbose #{hostname}", :accept_all_exit_codes => true).stderr.match(ipv4_regex)
26
- return match ? match[0] : nil
27
- end
28
-
29
- # @!macro [new] common_opts
30
- # @param [Hash{Symbol=>String}] opts Options to alter execution.
31
- # @option opts [Boolean] :silent (false) Do not produce log output
32
- # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
33
- # (or range) of integer exit codes that should be considered
34
- # acceptable. An error will be thrown if the exit code does not
35
- # match one of the values in this list.
36
- # @option opts [Boolean] :accept_all_exit_codes (false) Consider all
37
- # exit codes as passing.
38
- # @option opts [Boolean] :dry_run (false) Do not actually execute any
39
- # commands on the SUT
40
- # @option opts [String] :stdin (nil) Input to be provided during command
41
- # execution on the SUT.
42
- # @option opts [Boolean] :pty (false) Execute this command in a pseudoterminal.
43
- # @option opts [Boolean] :expect_connection_failure (false) Expect this command
44
- # to result in a connection failure, reconnect and continue execution.
45
- # @option opts [Hash{String=>String}] :environment ({}) These will be
46
- # treated as extra environment variables that should be set before
47
- # running the command.
48
- #
49
-
50
- # Return the name of the puppet user.
51
- #
52
- # @param [Host] host One object that acts like a Beaker::Host
53
- #
54
- # @note This method assumes puppet is installed on the host.
55
- #
56
- def puppet_user(host)
57
- return host.puppet('master')['user']
58
- end
59
-
60
- # Return the name of the puppet group.
61
- #
62
- # @param [Host] host One object that acts like a Beaker::Host
63
- #
64
- # @note This method assumes puppet is installed on the host.
65
- #
66
- def puppet_group(host)
67
- return host.puppet('master')['group']
68
- end
69
-
70
- # Test Puppet running in a certain run mode with specific options.
71
- # This ensures the following steps are performed:
72
- # 1. The pre-test Puppet configuration is backed up
73
- # 2. A new Puppet configuraton file is layed down
74
- # 3. Puppet is started or restarted in the specified run mode
75
- # 4. Ensure Puppet has started correctly
76
- # 5. Further tests are yielded to
77
- # 6. Revert Puppet to the pre-test state
78
- # 7. Testing artifacts are saved in a folder named for the test
79
- #
80
- # @note Whether Puppet is started or restarted depends on what kind of
81
- # server you're running. Passenger and puppetserver are restarted before.
82
- # Webrick is started before and stopped after yielding, unless you're using
83
- # service scripts, then it'll behave like passenger & puppetserver.
84
- # Passenger and puppetserver (or webrick using service scripts)
85
- # restart after yielding by default. You can stop this from happening
86
- # by setting the :restart_when_done flag of the conf_opts argument.
87
- #
88
- # @param [Host] host One object that act like Host
89
- #
90
- # @param [Hash{Symbol=>String}] conf_opts Represents puppet settings.
91
- # Sections of the puppet.conf may be
92
- # specified, if no section is specified the
93
- # a puppet.conf file will be written with the
94
- # options put in a section named after [mode]
95
- # @option conf_opts [String] :__commandline_args__ A special setting for
96
- # command_line arguments such as --debug or
97
- # --logdest, which cannot be set in
98
- # puppet.conf. For example:
99
- #
100
- # :__commandline_args__ => '--logdest /tmp/a.log'
101
- #
102
- # These will only be applied when starting a FOSS
103
- # master, as a pe master is just bounced.
104
- # @option conf_opts [Hash] :__service_args__ A special setting of options
105
- # for controlling how the puppet master service is
106
- # handled. The only setting currently is
107
- # :bypass_service_script, which if set true will
108
- # force stopping and starting a webrick master
109
- # using the start_puppet_from_source_* methods,
110
- # even if it seems the host has passenger.
111
- # This is needed in FOSS tests to initialize
112
- # SSL.
113
- # @option conf_opts [Boolean] :restart_when_done determines whether a restart
114
- # should be run after the test has been yielded to.
115
- # Will stop puppet if false. Default behavior
116
- # is to restart, but you can override this on the
117
- # host or with this option.
118
- # (Note: only works for passenger & puppetserver
119
- # masters (or webrick using the service scripts))
120
- # @param [File] testdir The temporary directory which will hold backup
121
- # configuration, and other test artifacts.
122
- #
123
- # @param [Block] block The point of this method, yields so
124
- # tests may be ran. After the block is finished
125
- # puppet will revert to a previous state.
126
- #
127
- # @example A simple use case to ensure a master is running
128
- # with_puppet_running_on( master ) do
129
- # ...tests that require a master...
130
- # end
131
- #
132
- # @example Fully utilizing the possiblities of config options
133
- # with_puppet_running_on( master,
134
- # :main => {:logdest => '/var/blah'},
135
- # :master => {:masterlog => '/elswhere'},
136
- # :agent => {:server => 'localhost'} ) do
137
- #
138
- # ...tests to be ran...
139
- # end
140
- #
141
- def with_puppet_running_on host, conf_opts, testdir = host.tmpdir(File.basename(@path)), &block
142
- raise(ArgumentError, "with_puppet_running_on's conf_opts must be a Hash. You provided a #{conf_opts.class}: '#{conf_opts}'") if !conf_opts.kind_of?(Hash)
143
- cmdline_args = conf_opts[:__commandline_args__]
144
- service_args = conf_opts[:__service_args__] || {}
145
- restart_when_done = true
146
- restart_when_done = host[:restart_when_done] if host.has_key?(:restart_when_done)
147
- restart_when_done = conf_opts.fetch(:restart_when_done, restart_when_done)
148
- conf_opts = conf_opts.reject { |k,v| [:__commandline_args__, :__service_args__, :restart_when_done].include?(k) }
149
-
150
- curl_retries = host['master-start-curl-retries'] || options['master-start-curl-retries']
151
- logger.debug "Setting curl retries to #{curl_retries}"
152
-
153
- if options[:is_puppetserver] || host[:is_puppetserver]
154
- confdir = host.puppet('master')['confdir']
155
- vardir = host.puppet('master')['vardir']
156
-
157
- if cmdline_args
158
- split_args = cmdline_args.split()
159
-
160
- split_args.each do |arg|
161
- case arg
162
- when /--confdir=(.*)/
163
- confdir = $1
164
- when /--vardir=(.*)/
165
- vardir = $1
166
- end
167
- end
168
- end
169
-
170
- puppetserver_opts = { "jruby-puppet" => {
171
- "master-conf-dir" => confdir,
172
- "master-var-dir" => vardir,
173
- }}
174
-
175
- puppetserver_conf = File.join("#{host['puppetserver-confdir']}", "puppetserver.conf")
176
- modify_tk_config(host, puppetserver_conf, puppetserver_opts)
177
- end
178
- begin
179
- backup_file = backup_the_file(host, host.puppet('master')['confdir'], testdir, 'puppet.conf')
180
- lay_down_new_puppet_conf host, conf_opts, testdir
181
-
182
- if host.use_service_scripts? && !service_args[:bypass_service_script]
183
- bounce_service( host, host['puppetservice'], curl_retries )
184
- else
185
- puppet_master_started = start_puppet_from_source_on!( host, cmdline_args )
186
- end
187
-
188
- yield self if block_given?
189
-
190
- # FIXME: these test-flow-control exceptions should be using throw
191
- # they can be caught in test_case. current layout dows not allow it
192
- rescue Beaker::DSL::Outcomes::PassTest => early_assertion
193
- pass_test(early_assertion)
194
- rescue Beaker::DSL::Outcomes::FailTest => early_assertion
195
- fail_test(early_assertion)
196
- rescue Beaker::DSL::Outcomes::PendingTest => early_assertion
197
- pending_test(early_assertion)
198
- rescue Beaker::DSL::Outcomes::SkipTest => early_assertion
199
- skip_test(early_assertion)
200
- rescue Beaker::DSL::Assertions, Minitest::Assertion => early_assertion
201
- fail_test(early_assertion)
202
- rescue Exception => early_exception
203
- original_exception = RuntimeError.new("PuppetAcceptance::DSL::Helpers.with_puppet_running_on failed (check backtrace for location) because: #{early_exception}\n#{early_exception.backtrace.join("\n")}\n")
204
- raise(original_exception)
205
-
206
- ensure
207
- begin
208
-
209
- if host.use_service_scripts? && !service_args[:bypass_service_script]
210
- restore_puppet_conf_from_backup( host, backup_file )
211
- if restart_when_done
212
- bounce_service( host, host['puppetservice'], curl_retries )
213
- else
214
- host.exec puppet_resource('service', host['puppetservice'], 'ensure=stopped')
215
- end
216
- else
217
- if puppet_master_started
218
- stop_puppet_from_source_on( host )
219
- else
220
- dump_puppet_log(host)
221
- end
222
- restore_puppet_conf_from_backup( host, backup_file )
223
- end
224
-
225
- rescue Exception => teardown_exception
226
- begin
227
- if !host.is_pe?
228
- dump_puppet_log(host)
229
- end
230
- rescue Exception => dumping_exception
231
- logger.error("Raised during attempt to dump puppet logs: #{dumping_exception}")
232
- end
233
-
234
- if original_exception
235
- logger.error("Raised during attempt to teardown with_puppet_running_on: #{teardown_exception}\n---\n")
236
- raise original_exception
237
- else
238
- raise teardown_exception
239
- end
240
- end
241
- end
242
- end
243
-
244
- # Test Puppet running in a certain run mode with specific options,
245
- # on the default host
246
- # @see #with_puppet_running_on
247
- def with_puppet_running conf_opts, testdir = host.tmpdir(File.basename(@path)), &block
248
- with_puppet_running_on(default, conf_opts, testdir, &block)
249
- end
250
-
251
- # @!visibility private
252
- def restore_puppet_conf_from_backup( host, backup_file )
253
- puppet_conf = host.puppet('master')['config']
254
-
255
- if backup_file
256
- host.exec( Command.new( "if [ -f '#{backup_file}' ]; then " +
257
- "cat '#{backup_file}' > " +
258
- "'#{puppet_conf}'; " +
259
- "rm -f '#{backup_file}'; " +
260
- "fi" ) )
261
- else
262
- host.exec( Command.new( "rm -f '#{puppet_conf}'" ))
263
- end
264
-
265
- end
266
-
267
- # @!visibility private
268
- def start_puppet_from_source_on! host, args = ''
269
- host.exec( puppet( 'master', args ) )
270
-
271
- logger.debug 'Waiting for the puppet master to start'
272
- unless port_open_within?( host, 8140, 10 )
273
- raise Beaker::DSL::FailTest, 'Puppet master did not start in a timely fashion'
274
- end
275
- logger.debug 'The puppet master has started'
276
- return true
277
- end
278
-
279
- # @!visibility private
280
- def stop_puppet_from_source_on( host )
281
- pid = host.exec( Command.new('cat `puppet master --configprint pidfile`') ).stdout.chomp
282
- host.exec( Command.new( "kill #{pid}" ) )
283
- Timeout.timeout(10) do
284
- while host.exec( Command.new( "kill -0 #{pid}"), :acceptable_exit_codes => [0,1] ).exit_code == 0 do
285
- # until kill -0 finds no process and we know that puppet has finished cleaning up
286
- sleep 1
287
- end
288
- end
289
- end
290
-
291
- # @!visibility private
292
- def dump_puppet_log(host)
293
- syslogfile = case host['platform']
294
- when /fedora|centos|el|redhat|scientific/ then '/var/log/messages'
295
- when /ubuntu|debian|cumulus/ then '/var/log/syslog'
296
- else return
297
- end
298
-
299
- logger.notify "\n*************************"
300
- logger.notify "* Dumping master log *"
301
- logger.notify "*************************"
302
- host.exec( Command.new( "tail -n 100 #{syslogfile}" ), :acceptable_exit_codes => [0,1])
303
- logger.notify "*************************\n"
304
- end
305
-
306
- # @!visibility private
307
- def lay_down_new_puppet_conf( host, configuration_options, testdir )
308
- puppetconf_main = host.puppet('master')['config']
309
- puppetconf_filename = File.basename(puppetconf_main)
310
- puppetconf_test = File.join(testdir, puppetconf_filename)
311
-
312
- new_conf = puppet_conf_for( host, configuration_options )
313
- create_remote_file host, puppetconf_test, new_conf.to_s
314
-
315
- host.exec(
316
- Command.new( "cat #{puppetconf_test} > #{puppetconf_main}" ),
317
- :silent => true
318
- )
319
- host.exec( Command.new( "cat #{puppetconf_main}" ) )
320
- end
321
-
322
- # @!visibility private
323
- def puppet_conf_for host, conf_opts
324
- puppetconf = host.exec( Command.new( "cat #{host.puppet('master')['config']}" ) ).stdout
325
- new_conf = IniFile.new(content: puppetconf).merge( conf_opts )
326
-
327
- new_conf
328
- end
329
-
330
- # Restarts the named puppet service
331
- #
332
- # @param [Host] host Host the service runs on
333
- # @param [String] service Name of the service to restart
334
- # @param [Fixnum] curl_retries Number of seconds to wait for the restart to complete before failing
335
- # @param [Fixnum] port Port to check status at
336
- #
337
- # @return [Result] Result of last status check
338
- # @!visibility private
339
- def bounce_service host, service, curl_retries = nil, port = nil
340
- curl_retries = 120 if curl_retries.nil?
341
- port = options[:puppetserver_port] if port.nil?
342
- if host.graceful_restarts?
343
- service = host.check_for_command('apache2ctl') ? 'apache2ctl' : 'apachectl'
344
- apachectl_path = host.is_pe? ? "#{host['puppetsbindir']}/#{service}" : service
345
- host.exec(Command.new("#{apachectl_path} graceful"))
346
- else
347
- result = host.exec(Command.new("service #{service} reload"),
348
- :acceptable_exit_codes => [0,1,3])
349
- if result.exit_code == 0
350
- return result
351
- else
352
- host.exec puppet_resource('service', service, 'ensure=stopped')
353
- host.exec puppet_resource('service', service, 'ensure=running')
354
- end
355
- end
356
- curl_with_retries(" #{service} ", host, "https://localhost:#{port}", [35, 60], curl_retries)
357
- end
358
-
359
- # Runs 'puppet apply' on a remote host, piping manifest through stdin
360
- #
361
- # @param [Host] host The host that this command should be run on
362
- #
363
- # @param [String] manifest The puppet manifest to apply
364
- #
365
- # @!macro common_opts
366
- # @option opts [Boolean] :parseonly (false) If this key is true, the
367
- # "--parseonly" command line parameter will
368
- # be passed to the 'puppet apply' command.
369
- #
370
- # @option opts [Boolean] :trace (false) If this key exists in the Hash,
371
- # the "--trace" command line parameter will be
372
- # passed to the 'puppet apply' command.
373
- #
374
- # @option opts [Array<Integer>] :acceptable_exit_codes ([0]) The list of exit
375
- # codes that will NOT raise an error when found upon
376
- # command completion. If provided, these values will
377
- # be combined with those used in :catch_failures and
378
- # :expect_failures to create the full list of
379
- # passing exit codes.
380
- #
381
- # @option opts [Hash] :environment Additional environment variables to be
382
- # passed to the 'puppet apply' command
383
- #
384
- # @option opts [Boolean] :catch_failures (false) By default `puppet
385
- # --apply` will exit with 0, which does not count
386
- # as a test failure, even if there were errors or
387
- # changes when applying the manifest. This option
388
- # enables detailed exit codes and causes a test
389
- # failure if `puppet --apply` indicates there was
390
- # a failure during its execution.
391
- #
392
- # @option opts [Boolean] :catch_changes (false) This option enables
393
- # detailed exit codes and causes a test failure
394
- # if `puppet --apply` indicates that there were
395
- # changes or failures during its execution.
396
- #
397
- # @option opts [Boolean] :expect_changes (false) This option enables
398
- # detailed exit codes and causes a test failure
399
- # if `puppet --apply` indicates that there were
400
- # no resource changes during its execution.
401
- #
402
- # @option opts [Boolean] :expect_failures (false) This option enables
403
- # detailed exit codes and causes a test failure
404
- # if `puppet --apply` indicates there were no
405
- # failure during its execution.
406
- #
407
- # @option opts [Boolean] :future_parser (false) This option enables
408
- # the future parser option that is available
409
- # from Puppet verion 3.2
410
- # By default it will use the 'current' parser.
411
- #
412
- # @option opts [Boolean] :noop (false) If this option exists, the
413
- # the "--noop" command line parameter will be
414
- # passed to the 'puppet apply' command.
415
- #
416
- # @option opts [String] :modulepath The search path for modules, as
417
- # a list of directories separated by the system
418
- # path separator character. (The POSIX path separator
419
- # is ‘:’, and the Windows path separator is ‘;’.)
420
- #
421
- # @option opts [String] :debug (false) If this option exists,
422
- # the "--debug" command line parameter
423
- # will be passed to the 'puppet apply' command.
424
- # @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
425
- #
426
- # @param [Block] block This method will yield to a block of code passed
427
- # by the caller; this can be used for additional
428
- # validation, etc.
429
- #
430
- # @return [Array<Result>, Result, nil] An array of results, a result object,
431
- # or nil. Check {#run_block_on} for more details on this.
432
- def apply_manifest_on(host, manifest, opts = {}, &block)
433
- block_on host, opts do | host |
434
- on_options = {}
435
- on_options[:acceptable_exit_codes] = Array(opts[:acceptable_exit_codes])
436
-
437
- puppet_apply_opts = {}
438
- if opts[:debug]
439
- puppet_apply_opts[:debug] = nil
440
- else
441
- puppet_apply_opts[:verbose] = nil
442
- end
443
- puppet_apply_opts[:parseonly] = nil if opts[:parseonly]
444
- puppet_apply_opts[:trace] = nil if opts[:trace]
445
- puppet_apply_opts[:parser] = 'future' if opts[:future_parser]
446
- puppet_apply_opts[:modulepath] = opts[:modulepath] if opts[:modulepath]
447
- puppet_apply_opts[:noop] = nil if opts[:noop]
448
-
449
- # From puppet help:
450
- # "... an exit code of '2' means there were changes, an exit code of
451
- # '4' means there were failures during the transaction, and an exit
452
- # code of '6' means there were both changes and failures."
453
- if [opts[:catch_changes],opts[:catch_failures],opts[:expect_failures],opts[:expect_changes]].compact.length > 1
454
- raise(ArgumentError,
455
- 'Cannot specify more than one of `catch_failures`, ' +
456
- '`catch_changes`, `expect_failures`, or `expect_changes` ' +
457
- 'for a single manifest')
458
- end
459
-
460
- if opts[:catch_changes]
461
- puppet_apply_opts['detailed-exitcodes'] = nil
462
-
463
- # We're after idempotency so allow exit code 0 only.
464
- on_options[:acceptable_exit_codes] |= [0]
465
- elsif opts[:catch_failures]
466
- puppet_apply_opts['detailed-exitcodes'] = nil
467
-
468
- # We're after only complete success so allow exit codes 0 and 2 only.
469
- on_options[:acceptable_exit_codes] |= [0, 2]
470
- elsif opts[:expect_failures]
471
- puppet_apply_opts['detailed-exitcodes'] = nil
472
-
473
- # We're after failures specifically so allow exit codes 1, 4, and 6 only.
474
- on_options[:acceptable_exit_codes] |= [1, 4, 6]
475
- elsif opts[:expect_changes]
476
- puppet_apply_opts['detailed-exitcodes'] = nil
477
-
478
- # We're after changes specifically so allow exit code 2 only.
479
- on_options[:acceptable_exit_codes] |= [2]
480
- else
481
- # Either use the provided acceptable_exit_codes or default to [0]
482
- on_options[:acceptable_exit_codes] |= [0]
483
- end
484
-
485
- # Not really thrilled with this implementation, might want to improve it
486
- # later. Basically, there is a magic trick in the constructor of
487
- # PuppetCommand which allows you to pass in a Hash for the last value in
488
- # the *args Array; if you do so, it will be treated specially. So, here
489
- # we check to see if our caller passed us a hash of environment variables
490
- # that they want to set for the puppet command. If so, we set the final
491
- # value of *args to a new hash with just one entry (the value of which
492
- # is our environment variables hash)
493
- if opts.has_key?(:environment)
494
- puppet_apply_opts['ENV'] = opts[:environment]
495
- end
496
-
497
- file_path = host.tmpfile('apply_manifest.pp')
498
- create_remote_file(host, file_path, manifest + "\n")
499
-
500
- if host[:default_apply_opts].respond_to? :merge
501
- puppet_apply_opts = host[:default_apply_opts].merge( puppet_apply_opts )
502
- end
503
-
504
- on host, puppet('apply', file_path, puppet_apply_opts), on_options, &block
505
- end
506
- end
507
-
508
- # Runs 'puppet apply' on default host, piping manifest through stdin
509
- # @see #apply_manifest_on
510
- def apply_manifest(manifest, opts = {}, &block)
511
- apply_manifest_on(default, manifest, opts, &block)
512
- end
513
-
514
- # @deprecated
515
- def run_agent_on(host, arg='--no-daemonize --verbose --onetime --test',
516
- options={}, &block)
517
- block_on host do | host |
518
- on host, puppet_agent(arg), options, &block
519
- end
520
- end
521
-
522
- # This method using the puppet resource 'host' will setup host aliases
523
- # and register the remove of host aliases via Beaker::TestCase#teardown
524
- #
525
- # A teardown step is also added to make sure unstubbing of the host is
526
- # removed always.
527
- #
528
- # @param [Host, Array<Host>, String, Symbol] machine One or more hosts to act upon,
529
- # or a role (String or Symbol) that identifies one or more hosts.
530
- # @param ip_spec [Hash{String=>String}] a hash containing the host to ip
531
- # mappings
532
- # @param alias_spec [Hash{String=>Array[String]] an hash containing the host to alias(es) mappings to apply
533
- # @example Stub puppetlabs.com on the master to 127.0.0.1 with an alias example.com
534
- # stub_hosts_on(master, {'puppetlabs.com' => '127.0.0.1'}, {'puppetlabs.com' => ['example.com']})
535
- def stub_hosts_on(machine, ip_spec, alias_spec={})
536
- block_on machine do | host |
537
- ip_spec.each do |address, ip|
538
- aliases = alias_spec[address] || []
539
- manifest =<<-EOS.gsub /^\s+/, ""
540
- host { '#{address}':
541
- \tensure => present,
542
- \tip => '#{ip}',
543
- \thost_aliases => #{aliases},
544
- }
545
- EOS
546
- logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}")
547
- apply_manifest_on( host, manifest )
548
- end
549
-
550
- teardown do
551
- ip_spec.each do |address, ip|
552
- logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}")
553
- on( host, puppet('resource', 'host', address, 'ensure=absent') )
554
- end
555
- end
556
- end
557
- end
558
-
559
- # This method accepts a block and using the puppet resource 'host' will
560
- # setup host aliases before and after that block.
561
- #
562
- # @param [Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
563
- # or a role (String or Symbol) that identifies one or more hosts.
564
- # @param ip_spec [Hash{String=>String}] a hash containing the host to ip
565
- # mappings
566
- # @param alias_spec [Hash{String=>Array[String]] an hash containing the host to alias(es) mappings to apply
567
- # @example Stub forgeapi.puppetlabs.com on the master to 127.0.0.1 with an alias forgeapi.example.com
568
- # with_host_stubbed_on(master, {'forgeapi.puppetlabs.com' => '127.0.0.1'}, {'forgeapi.puppetlabs.com' => ['forgeapi.example.com']}) do
569
- # puppet( "module install puppetlabs-stdlib" )
570
- # end
571
- def with_host_stubbed_on(host, ip_spec, alias_spec={}, &block)
572
- begin
573
- block_on host do |host|
574
- # this code is duplicated from the `stub_hosts_on` method. The
575
- # `stub_hosts_on` method itself is not used here because this
576
- # method is used by modules tests using `beaker-rspec`. Since
577
- # the `stub_hosts_on` method contains a `teardown` step, it is
578
- # incompatible with `beaker_rspec`.
579
- ip_spec.each do |address, ip|
580
- aliases = alias_spec[address] || []
581
- manifest =<<-EOS.gsub /^\s+/, ""
582
- host { '#{address}':
583
- \tensure => present,
584
- \tip => '#{ip}',
585
- \thost_aliases => #{aliases},
586
- }
587
- EOS
588
- logger.notify("Stubbing address #{address} to IP #{ip} on machine #{host}")
589
- apply_manifest_on( host, manifest )
590
- end
591
- end
592
-
593
- block.call
594
-
595
- ensure
596
- ip_spec.each do |address, ip|
597
- logger.notify("Unstubbing address #{address} to IP #{ip} on machine #{host}")
598
- on( host, puppet('resource', 'host', address, 'ensure=absent') )
599
- end
600
- end
601
- end
602
-
603
- # This method accepts a block and using the puppet resource 'host' will
604
- # setup host aliases before and after that block on the default host
605
- #
606
- # @example Stub puppetlabs.com on the default host to 127.0.0.1
607
- # stub_hosts('puppetlabs.com' => '127.0.0.1')
608
- # @see #stub_hosts_on
609
- def stub_hosts(ip_spec)
610
- stub_hosts_on(default, ip_spec)
611
- end
612
-
613
- # This wraps the method `stub_hosts_on` and makes the stub specific to
614
- # the forge alias.
615
- #
616
- # forge api v1 canonical source is forge.puppetlabs.com
617
- # forge api v3 canonical source is forgeapi.puppetlabs.com
618
- #
619
- # @param machine [String] the host to perform the stub on
620
- # @param forge_host [String] The URL to use as the forge alias, will default to using :forge_host in the
621
- # global options hash
622
- def stub_forge_on(machine, forge_host = nil)
623
- #use global options hash
624
- primary_forge_name = 'forge.puppetlabs.com'
625
- forge_host ||= options[:forge_host]
626
- forge_ip = resolve_hostname_on(machine, forge_host)
627
- raise "Failed to resolve forge host '#{forge_host}'" unless forge_ip
628
- @forge_ip ||= forge_ip
629
- block_on machine do | host |
630
- stub_hosts_on(host, {primary_forge_name => @forge_ip}, {primary_forge_name => ['forge.puppet.com','forgeapi.puppetlabs.com','forgeapi.puppet.com']})
631
- end
632
- end
633
-
634
- # This wraps the method `with_host_stubbed_on` and makes the stub specific to
635
- # the forge alias.
636
- #
637
- # forge api v1 canonical source is forge.puppetlabs.com
638
- # forge api v3 canonical source is forgeapi.puppetlabs.com
639
- #
640
- # @param host [String] the host to perform the stub on
641
- # @param forge_host [String] The URL to use as the forge alias, will default to using :forge_host in the
642
- # global options hash
643
- def with_forge_stubbed_on( host, forge_host = nil, &block )
644
- #use global options hash
645
- primary_forge_name = 'forge.puppetlabs.com'
646
- forge_host ||= options[:forge_host]
647
- forge_ip = resolve_hostname_on(host, forge_host)
648
- raise "Failed to resolve forge host '#{forge_host}'" unless forge_ip
649
- @forge_ip ||= forge_ip
650
- with_host_stubbed_on( host, {primary_forge_name => @forge_ip}, {primary_forge_name => ['forge.puppet.com','forgeapi.puppetlabs.com','forgeapi.puppet.com']}, &block )
651
- end
652
-
653
- # This wraps `with_forge_stubbed_on` and provides it the default host
654
- # @see with_forge_stubbed_on
655
- def with_forge_stubbed( forge_host = nil, &block )
656
- with_forge_stubbed_on( default, forge_host, &block )
657
- end
658
-
659
- # This wraps the method `stub_hosts` and makes the stub specific to
660
- # the forge alias.
661
- #
662
- # @see #stub_forge_on
663
- def stub_forge(forge_host = nil)
664
- #use global options hash
665
- forge_host ||= options[:forge_host]
666
- stub_forge_on(default, forge_host)
667
- end
668
-
669
- # Waits until a successful curl check has happened against puppetdb
670
- #
671
- # @param [Host] host Host puppetdb is on
672
- # @param [Fixnum] nonssl_port Port to make the HTTP status check over
673
- # @param [Fixnum] ssl_port Port to make the HTTPS status check over
674
- #
675
- # @return [Result] Result of the last HTTPS status check
676
- def sleep_until_puppetdb_started(host, nonssl_port = nil, ssl_port = nil)
677
- nonssl_port = options[:puppetdb_port_nonssl] if nonssl_port.nil?
678
- ssl_port = options[:puppetdb_port_ssl] if ssl_port.nil?
679
- pe_ver = host['pe_ver'] || '0'
680
- if version_is_less(pe_ver, '2016.1.0') then
681
- # the status endpoint was introduced in puppetdb 4.0. The earliest
682
- # PE release with the 4.x pdb version was 2016.1.0
683
- endpoint = 'pdb/meta/v1/version'
684
- expected_regex = '\"version\" \{0,\}: \{0,\}\"[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\"'
685
- else
686
- endpoint = 'status/v1/services/puppetdb-status'
687
- expected_regex = '\"state\" \{0,\}: \{0,\}\"running\"'
688
- end
689
- retry_on(host,
690
- "curl -m 1 http://localhost:#{nonssl_port}/#{endpoint} | grep '#{expected_regex}'",
691
- {:max_retries => 120})
692
- curl_with_retries("start puppetdb (ssl)",
693
- host, "https://#{host.node_name}:#{ssl_port}", [35, 60])
694
- end
695
-
696
- # Waits until a successful curl check has happened against puppetserver
697
- #
698
- # @param [Host] host Host puppetserver is on
699
- # @param [Fixnum] port Port to make the HTTPS status check over
700
- #
701
- # @return [Result] Result of the last HTTPS status check
702
- def sleep_until_puppetserver_started(host, port = nil)
703
- port = options[:puppetserver_port] if port.nil?
704
- curl_with_retries("start puppetserver (ssl)",
705
- host, "https://#{host.node_name}:#{port}", [35, 60])
706
- end
707
-
708
- # Waits until a successful curl check has happaned against node classifier
709
- #
710
- # @param [Host] host Host node classifier is on
711
- # @param [Fixnum] port Port to make the HTTPS status check over
712
- #
713
- # @return [Result] Result of the last HTTPS status check
714
- def sleep_until_nc_started(host, port = nil)
715
- port = options[:nodeclassifier_port] if port.nil?
716
- curl_with_retries("start nodeclassifier (ssl)",
717
- host, "https://#{host.node_name}:#{port}", [35, 60])
718
- end
719
-
720
- #stops the puppet agent running on the host
721
- # @param [Host, Array<Host>, String, Symbol] agent One or more hosts to act upon,
722
- # or a role (String or Symbol) that identifies one or more hosts.
723
- # @param [Hash{Symbol=>String}] opts Options to alter execution.
724
- # @option opts [Boolean] :run_in_parallel Whether to run on each host in parallel.
725
- def stop_agent_on(agent, opts = {})
726
- block_on agent, opts do | host |
727
- vardir = host.puppet_configprint['vardir']
728
- agent_running = true
729
- while agent_running
730
- agent_running = host.file_exist?("#{vardir}/state/agent_catalog_run.lock")
731
- if agent_running
732
- sleep 2
733
- end
734
- end
735
-
736
- # In 4.0 this was changed to just be `puppet`
737
- agent_service = 'puppet'
738
- if !aio_version?(host)
739
- # The agent service is `pe-puppet` everywhere EXCEPT certain linux distros on PE 2.8
740
- # In all the case that it is different, this init script will exist. So we can assume
741
- # that if the script doesn't exist, we should just use `pe-puppet`
742
- agent_service = 'pe-puppet-agent'
743
- agent_service = 'pe-puppet' unless host.file_exist?('/etc/init.d/pe-puppet-agent')
744
- end
745
-
746
- # Under a number of stupid circumstances, we can't stop the
747
- # agent using puppet. This is usually because of issues with
748
- # the init script or system on that particular configuration.
749
- avoid_puppet_at_all_costs = false
750
- avoid_puppet_at_all_costs ||= host['platform'] =~ /el-4/
751
- avoid_puppet_at_all_costs ||= host['pe_ver'] && version_is_less(host['pe_ver'], '3.2') && host['platform'] =~ /sles/
752
-
753
- if avoid_puppet_at_all_costs
754
- # When upgrading, puppet is already stopped. On EL4, this causes an exit code of '1'
755
- on host, "/etc/init.d/#{agent_service} stop", :acceptable_exit_codes => [0, 1]
756
- else
757
- on host, puppet_resource('service', agent_service, 'ensure=stopped')
758
- end
759
- end
760
- end
761
-
762
- #stops the puppet agent running on the default host
763
- # @see #stop_agent_on
764
- def stop_agent
765
- stop_agent_on(default)
766
- end
767
-
768
- #wait for a given host to appear in the dashboard
769
- # @deprecated this method should be removed in the next release since we don't believe the check is necessary.
770
- def wait_for_host_in_dashboard(host)
771
-
772
- hostname = host.node_name
773
- hostcert = dashboard.puppet['hostcert']
774
- key = dashboard.puppet['hostprivkey']
775
- cacert = dashboard.puppet['localcacert']
776
- retry_on(dashboard, "curl --cert #{hostcert} --key #{key} --cacert #{cacert}\
777
- https://#{dashboard}:4433/classifier-api/v1/nodes | grep '\"name\":\"#{hostname}\"'")
778
- end
779
-
780
- # Ensure the host has requested a cert, then sign it
781
- #
782
- # @param [Host, Array<Host>, String, Symbol] host One or more hosts, or a role (String or Symbol)
783
- # that identifies one or more hosts to validate certificate signing.
784
- # No argument, or an empty array means no validation of success
785
- # for specific hosts will be performed. This will always execute
786
- # 'cert --sign --all --allow-dns-alt-names' even for a single host.
787
- #
788
- # @return nil
789
- # @raise [FailTest] if process times out
790
- def sign_certificate_for(host = [])
791
- hostnames = []
792
- hosts = host.is_a?(Array) ? host : [host]
793
- hosts.each{ |current_host|
794
- if [master, dashboard, database].include? current_host
795
-
796
- on current_host, puppet( 'agent -t' ), :acceptable_exit_codes => [0,1,2]
797
- on master, puppet( "cert --allow-dns-alt-names sign #{current_host}" ), :acceptable_exit_codes => [0,24]
798
-
799
- else
800
- hostnames << Regexp.escape( current_host.node_name )
801
- end
802
- }
803
- if hostnames.size < 1
804
- on master, puppet("cert --sign --all --allow-dns-alt-names"),
805
- :acceptable_exit_codes => [0,24]
806
- return
807
- end
808
- while hostnames.size > 0
809
- last_sleep = 0
810
- next_sleep = 1
811
- (0..10).each do |i|
812
- if i == 10
813
- fail_test("Failed to sign cert for #{hostnames}")
814
- hostnames.clear
815
- end
816
- on master, puppet("cert --sign --all --allow-dns-alt-names"), :acceptable_exit_codes => [0,24]
817
- out = on(master, puppet("cert --list --all")).stdout
818
- if hostnames.all? { |hostname| out =~ /\+ "?#{hostname}"?/ }
819
- hostnames.clear
820
- break
821
- end
822
-
823
- sleep next_sleep
824
- (last_sleep, next_sleep) = next_sleep, last_sleep+next_sleep
825
- end
826
- end
827
- host
828
- end
829
-
830
- #prompt the master to sign certs then check to confirm the cert for the default host is signed
831
- #@see #sign_certificate_for
832
- def sign_certificate
833
- sign_certificate_for(default)
834
- end
835
-
836
- # Create a temp directory on remote host with a user. Default user
837
- # is puppet master user.
838
- #
839
- # @param [Host] host A single remote host on which to create and adjust
840
- # the ownership of a temp directory.
841
- # @param [String] name A remote path prefix for the new temp
842
- # directory. Default value is '/tmp/beaker'
843
- # @param [String] user The name of user that should own the temp
844
- # directory. If no username is specified, use `puppet master
845
- # --configprint user` to obtain username from master. Raise RuntimeError
846
- # if this puppet command returns a non-zero exit code.
847
- #
848
- # @return [String] Returns the name of the newly-created dir.
849
- def create_tmpdir_for_user(host, name='/tmp/beaker', user=nil)
850
- if not user
851
- result = on host, puppet("master --configprint user")
852
- if not result.exit_code == 0
853
- raise "`puppet master --configprint` failed, check that puppet is installed on #{host} or explicitly pass in a user name."
854
- end
855
- user = result.stdout.strip
856
- end
857
-
858
- create_tmpdir_on(host, name, user)
859
-
860
- end
861
-
862
- end
863
- end
864
- end
865
- end