beaker 4.24.0 → 4.28.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a564a311561c124625926ad527bf42a3fe0681e3a0a1c8f7780217a6b00f82dc
4
- data.tar.gz: 27c0f8cbae1a3f30226cb1dbc08db0cb4464e9e6340114b2b49d13b66e79d587
3
+ metadata.gz: '042089398937fe9ae306b0fa0e4f86f4ff4a1fb1c73bc986beb1a75f11d71d38'
4
+ data.tar.gz: 6d17864b513e99ecb311534a582a058e7ebcab9f8d525df29f5ec722210870ed
5
5
  SHA512:
6
- metadata.gz: 2f5c86fd2c82c44dd258d952d404741281a502dc2a2f987014795e940aa7e1f5f56937b628fe62a3fba8105a9f12866bd6a1a1367859f6ab9acbf6b7224d8d42
7
- data.tar.gz: 095358374f8ff2dfe5c0d95c41d5ff6ac621f69ef95a58580c7151d8f7d13bdbd89e0afa5b70be25ce0f3e14121b56c668765c78705bfe9868233cee37feb687
6
+ metadata.gz: ccdb8c321acd3dda9a015916f0c576d77b42c9a546cafe08f8a8b37e8e0fac59e593530d6eb2d631527de28a4c685b8c715f1be13024cceee42f075fd4d867e5
7
+ data.tar.gz: 01676fb8b0461b1dcfc363bbabf405e4af1e93449f025f6f3dd3b70103076862ccfc3e688e1b2fe1ebc03842f5734e5a6c802caca05028ddb0d3b43ca5e6ef87
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: "13:00"
8
+ open-pull-requests-limit: 10
@@ -0,0 +1,22 @@
1
+ name: Release
2
+
3
+ on:
4
+ create:
5
+ ref_type: tag
6
+
7
+ jobs:
8
+ release:
9
+ runs-on: ubuntu-latest
10
+ if: github.repository == 'voxpupuli/beaker'
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - name: Install Ruby 2.7
14
+ uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: '2.7'
17
+ - name: Build gem
18
+ run: gem build *.gemspec
19
+ - name: Publish gem
20
+ run: gem push *.gem
21
+ env:
22
+ GEM_HOST_API_KEY: '${{ secrets.RUBYGEMS_AUTH_TOKEN }}'
@@ -0,0 +1,29 @@
1
+ name: Test
2
+
3
+ on:
4
+ - pull_request
5
+ - push
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby:
14
+ - "2.4"
15
+ - "2.5"
16
+ - "2.6"
17
+ - "2.7"
18
+ name: Ruby ${{ matrix.ruby }}
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Install Ruby ${{ matrix.ruby }}
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby }}
25
+ bundler-cache: true
26
+ - name: Build docs
27
+ run: bundle exec rake yard
28
+ - name: Run tests
29
+ run: bundle exec rake spec
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
3
  --tty
4
+ --fail-fast
@@ -20,7 +20,62 @@ The headers used in [Keep a Changelog](http://keepachangelog.com) are:
20
20
  - Fixed - for any bug fixes.
21
21
  - Security - in case of vulnerabilities.
22
22
 
23
- # [Unreleased](https://github.com/puppetlabs/beaker/compare/4.23.2...master)
23
+ # [Unreleased](https://github.com/puppetlabs/beaker/compare/4.28.0...master)
24
+
25
+ # [4.28.0](https://github.com/puppetlabs/beaker/compare/4.27.1...4.28.0) - 12-21-2020
26
+
27
+ ### Changed
28
+
29
+ - Arch Linux: Update box before installing packages ([#1688](https://github.com/voxpupuli/beaker/pull/1688))
30
+ - Move the entire workflow to Github Actions ([#1678](https://github.com/voxpupuli/beaker/pull/1678))
31
+ - Allow fakefs dependency in version >= 1 < 2 ([#1687](https://github.com/voxpupuli/beaker/pull/1687))
32
+
33
+ ### Fixed
34
+
35
+ - Fix License text and SPDX code ([#1681](https://github.com/voxpupuli/beaker/pull/1678))
36
+
37
+ # [4.27.1](https://github.com/puppetlabs/beaker/compare/4.27.0...4.27.1) - 09-29-2020
38
+
39
+ ### Changed
40
+
41
+ - Update net-scp requirement from "~> 1.2" to ">= 1.2, < 4.0"
42
+
43
+ ### Fixed
44
+
45
+ - Handle systems going back in time after reboot
46
+ - Enhanced error handling during the reboot sequence
47
+ - Fixed time check logic during reboot
48
+ - Wrap paths around "" on pswindows
49
+
50
+ # [4.27.0](https://github.com/puppetlabs/beaker/compare/4.26.0...4.27.0) - 07-24-2020
51
+
52
+ ### Changed
53
+
54
+ - Updated dependency versions and minimum Ruby version in gemspec to Ruby 2.4, which is the minimum
55
+ version Beaker will run with.
56
+ - Added Travis unit testing and disabled Jenkins integrations in preparation for transferring the
57
+ repo to Vox Pupuli
58
+
59
+
60
+ # [4.26.0](https://github.com/puppetlabs/beaker/compare/4.25.0...4.26.0)
61
+
62
+ ### Changed
63
+
64
+ - Fixed deprecated SSH option handling for `verify_ssh_key` being passed into Net::SSH. #1655
65
+
66
+ ### Removed
67
+
68
+ - Removed deprecated use of `paranoid` flag with Net::SSH. #1655
69
+
70
+ # [4.25.0](https://github.com/puppetlabs/beaker/compare/4.24.0...4.25.0)
71
+
72
+ ### Added
73
+
74
+ - Execution of Beaker directly through ruby on localhost #1637 ([#1637](https://github.com/puppetlabs/beaker/pull/1637))
75
+
76
+ ### Fixed
77
+
78
+ - Reliability improvements to the `Host#reboot` method ([#1656](https://github.com/puppetlabs/beaker/pull/1656)) ([#1659](https://github.com/puppetlabs/beaker/pull/1659))
24
79
 
25
80
  # [4.24.0](https://github.com/puppetlabs/beaker/compare/4.23.0...4.24.0) - 2020-06-05
26
81
 
data/CODEOWNERS CHANGED
@@ -1,2 +0,0 @@
1
- * @puppetlabs/beaker
2
- * @puppetlabs/dio
data/LICENSE CHANGED
@@ -1,8 +1,194 @@
1
- beaker - Puppet's system level acceptance test harness
2
-
3
1
  Copyright (C) 2011-2015 Puppet Labs Inc
4
2
 
5
- Puppet Labs can be contacted at: info@puppetlabs.com
3
+ Apache License
4
+ Version 2.0, January 2004
5
+ http://www.apache.org/licenses/
6
+
7
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
+
9
+ 1. Definitions.
10
+
11
+ "License" shall mean the terms and conditions for use, reproduction,
12
+ and distribution as defined by Sections 1 through 9 of this document.
13
+
14
+ "Licensor" shall mean the copyright owner or entity authorized by
15
+ the copyright owner that is granting the License.
16
+
17
+ "Legal Entity" shall mean the union of the acting entity and all
18
+ other entities that control, are controlled by, or are under common
19
+ control with that entity. For the purposes of this definition,
20
+ "control" means (i) the power, direct or indirect, to cause the
21
+ direction or management of such entity, whether by contract or
22
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
23
+ outstanding shares, or (iii) beneficial ownership of such entity.
24
+
25
+ "You" (or "Your") shall mean an individual or Legal Entity
26
+ exercising permissions granted by this License.
27
+
28
+ "Source" form shall mean the preferred form for making modifications,
29
+ including but not limited to software source code, documentation
30
+ source, and configuration files.
31
+
32
+ "Object" form shall mean any form resulting from mechanical
33
+ transformation or translation of a Source form, including but
34
+ not limited to compiled object code, generated documentation,
35
+ and conversions to other media types.
36
+
37
+ "Work" shall mean the work of authorship, whether in Source or
38
+ Object form, made available under the License, as indicated by a
39
+ copyright notice that is included in or attached to the work
40
+ (an example is provided in the Appendix below).
41
+
42
+ "Derivative Works" shall mean any work, whether in Source or Object
43
+ form, that is based on (or derived from) the Work and for which the
44
+ editorial revisions, annotations, elaborations, or other modifications
45
+ represent, as a whole, an original work of authorship. For the purposes
46
+ of this License, Derivative Works shall not include works that remain
47
+ separable from, or merely link (or bind by name) to the interfaces of,
48
+ the Work and Derivative Works thereof.
49
+
50
+ "Contribution" shall mean any work of authorship, including
51
+ the original version of the Work and any modifications or additions
52
+ to that Work or Derivative Works thereof, that is intentionally
53
+ submitted to Licensor for inclusion in the Work by the copyright owner
54
+ or by an individual or Legal Entity authorized to submit on behalf of
55
+ the copyright owner. For the purposes of this definition, "submitted"
56
+ means any form of electronic, verbal, or written communication sent
57
+ to the Licensor or its representatives, including but not limited to
58
+ communication on electronic mailing lists, source code control systems,
59
+ and issue tracking systems that are managed by, or on behalf of, the
60
+ Licensor for the purpose of discussing and improving the Work, but
61
+ excluding communication that is conspicuously marked or otherwise
62
+ designated in writing by the copyright owner as "Not a Contribution."
63
+
64
+ "Contributor" shall mean Licensor and any individual or Legal Entity
65
+ on behalf of whom a Contribution has been received by Licensor and
66
+ subsequently incorporated within the Work.
67
+
68
+ 2. Grant of Copyright License. Subject to the terms and conditions of
69
+ this License, each Contributor hereby grants to You a perpetual,
70
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
71
+ copyright license to reproduce, prepare Derivative Works of,
72
+ publicly display, publicly perform, sublicense, and distribute the
73
+ Work and such Derivative Works in Source or Object form.
74
+
75
+ 3. Grant of Patent License. Subject to the terms and conditions of
76
+ this License, each Contributor hereby grants to You a perpetual,
77
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78
+ (except as stated in this section) patent license to make, have made,
79
+ use, offer to sell, sell, import, and otherwise transfer the Work,
80
+ where such license applies only to those patent claims licensable
81
+ by such Contributor that are necessarily infringed by their
82
+ Contribution(s) alone or by combination of their Contribution(s)
83
+ with the Work to which such Contribution(s) was submitted. If You
84
+ institute patent litigation against any entity (including a
85
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
86
+ or a Contribution incorporated within the Work constitutes direct
87
+ or contributory patent infringement, then any patent licenses
88
+ granted to You under this License for that Work shall terminate
89
+ as of the date such litigation is filed.
90
+
91
+ 4. Redistribution. You may reproduce and distribute copies of the
92
+ Work or Derivative Works thereof in any medium, with or without
93
+ modifications, and in Source or Object form, provided that You
94
+ meet the following conditions:
95
+
96
+ (a) You must give any other recipients of the Work or
97
+ Derivative Works a copy of this License; and
98
+
99
+ (b) You must cause any modified files to carry prominent notices
100
+ stating that You changed the files; and
101
+
102
+ (c) You must retain, in the Source form of any Derivative Works
103
+ that You distribute, all copyright, patent, trademark, and
104
+ attribution notices from the Source form of the Work,
105
+ excluding those notices that do not pertain to any part of
106
+ the Derivative Works; and
107
+
108
+ (d) If the Work includes a "NOTICE" text file as part of its
109
+ distribution, then any Derivative Works that You distribute must
110
+ include a readable copy of the attribution notices contained
111
+ within such NOTICE file, excluding those notices that do not
112
+ pertain to any part of the Derivative Works, in at least one
113
+ of the following places: within a NOTICE text file distributed
114
+ as part of the Derivative Works; within the Source form or
115
+ documentation, if provided along with the Derivative Works; or,
116
+ within a display generated by the Derivative Works, if and
117
+ wherever such third-party notices normally appear. The contents
118
+ of the NOTICE file are for informational purposes only and
119
+ do not modify the License. You may add Your own attribution
120
+ notices within Derivative Works that You distribute, alongside
121
+ or as an addendum to the NOTICE text from the Work, provided
122
+ that such additional attribution notices cannot be construed
123
+ as modifying the License.
124
+
125
+ You may add Your own copyright statement to Your modifications and
126
+ may provide additional or different license terms and conditions
127
+ for use, reproduction, or distribution of Your modifications, or
128
+ for any such Derivative Works as a whole, provided Your use,
129
+ reproduction, and distribution of the Work otherwise complies with
130
+ the conditions stated in this License.
131
+
132
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
133
+ any Contribution intentionally submitted for inclusion in the Work
134
+ by You to the Licensor shall be under the terms and conditions of
135
+ this License, without any additional terms or conditions.
136
+ Notwithstanding the above, nothing herein shall supersede or modify
137
+ the terms of any separate license agreement you may have executed
138
+ with Licensor regarding such Contributions.
139
+
140
+ 6. Trademarks. This License does not grant permission to use the trade
141
+ names, trademarks, service marks, or product names of the Licensor,
142
+ except as required for reasonable and customary use in describing the
143
+ origin of the Work and reproducing the content of the NOTICE file.
144
+
145
+ 7. Disclaimer of Warranty. Unless required by applicable law or
146
+ agreed to in writing, Licensor provides the Work (and each
147
+ Contributor provides its Contributions) on an "AS IS" BASIS,
148
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
149
+ implied, including, without limitation, any warranties or conditions
150
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
151
+ PARTICULAR PURPOSE. You are solely responsible for determining the
152
+ appropriateness of using or redistributing the Work and assume any
153
+ risks associated with Your exercise of permissions under this License.
154
+
155
+ 8. Limitation of Liability. In no event and under no legal theory,
156
+ whether in tort (including negligence), contract, or otherwise,
157
+ unless required by applicable law (such as deliberate and grossly
158
+ negligent acts) or agreed to in writing, shall any Contributor be
159
+ liable to You for damages, including any direct, indirect, special,
160
+ incidental, or consequential damages of any character arising as a
161
+ result of this License or out of the use or inability to use the
162
+ Work (including but not limited to damages for loss of goodwill,
163
+ work stoppage, computer failure or malfunction, or any and all
164
+ other commercial damages or losses), even if such Contributor
165
+ has been advised of the possibility of such damages.
166
+
167
+ 9. Accepting Warranty or Additional Liability. While redistributing
168
+ the Work or Derivative Works thereof, You may choose to offer,
169
+ and charge a fee for, acceptance of support, warranty, indemnity,
170
+ or other liability obligations and/or rights consistent with this
171
+ License. However, in accepting such obligations, You may act only
172
+ on Your own behalf and on Your sole responsibility, not on behalf
173
+ of any other Contributor, and only if You agree to indemnify,
174
+ defend, and hold each Contributor harmless for any liability
175
+ incurred by, or claims asserted against, such Contributor by reason
176
+ of your accepting any such warranty or additional liability.
177
+
178
+ END OF TERMS AND CONDITIONS
179
+
180
+ APPENDIX: How to apply the Apache License to your work.
181
+
182
+ To apply the Apache License to your work, attach the following
183
+ boilerplate notice, with the fields enclosed by brackets "[]"
184
+ replaced with your own identifying information. (Don't include
185
+ the brackets!) The text should be enclosed in the appropriate
186
+ comment syntax for the file format. We also recommend that a
187
+ file or class name and description of purpose be included on the
188
+ same "printed page" as the copyright notice for easier
189
+ identification within third-party archives.
190
+
191
+ Copyright [yyyy] [name of copyright owner]
6
192
 
7
193
  Licensed under the Apache License, Version 2.0 (the "License");
8
194
  you may not use this file except in compliance with the License.
data/Rakefile CHANGED
@@ -26,11 +26,6 @@ task :history do
26
26
  Rake::Task['history:gen'].invoke
27
27
  end
28
28
 
29
- task :travis do
30
- Rake::Task['yard'].invoke if !Beaker::Shared::Semvar.version_is_less(RUBY_VERSION, '2.0.0')
31
- Rake::Task['spec'].invoke
32
- end
33
-
34
29
  module HarnessOptions
35
30
  defaults = {
36
31
  :tests => ['tests'],
@@ -7,25 +7,25 @@ Gem::Specification.new do |s|
7
7
  s.name = "beaker"
8
8
  s.version = Beaker::Version::STRING
9
9
  s.authors = ["Puppet"]
10
- s.email = ["delivery@puppet.com"]
11
- s.homepage = "https://github.com/puppetlabs/beaker"
10
+ s.email = ["voxpupuli@groups.io"]
11
+ s.homepage = "https://github.com/voxpupuli/beaker"
12
12
  s.summary = %q{Let's test Puppet!}
13
13
  s.description = %q{Puppet's accceptance testing harness}
14
- s.license = 'Apache2'
14
+ s.license = 'Apache-2.0'
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.required_ruby_version = Gem::Requirement.new('>= 2.1.8')
21
+ s.required_ruby_version = Gem::Requirement.new('>= 2.4')
22
22
 
23
23
  # Testing dependencies
24
24
  s.add_development_dependency 'rspec', '~> 3.0'
25
25
  s.add_development_dependency 'rspec-its'
26
- s.add_development_dependency 'fakefs', '~> 0.6', '< 0.14.0'
26
+ s.add_development_dependency 'fakefs', '~> 1.0'
27
27
  s.add_development_dependency 'simplecov'
28
- s.add_development_dependency 'rake', '~> 12.0'
28
+ s.add_development_dependency 'rake', '~> 13.0'
29
29
 
30
30
  # Provisioner dependencies - needed for acceptance tests
31
31
  # TODO: figure out how to remove these
@@ -39,13 +39,13 @@ Gem::Specification.new do |s|
39
39
  # Run time dependencies
40
40
  s.add_runtime_dependency 'minitest', '~> 5.4'
41
41
  s.add_runtime_dependency 'minitar', '~> 0.6'
42
- s.add_runtime_dependency 'pry-byebug', '~> 3.6'
42
+ s.add_runtime_dependency 'pry-byebug', '~> 3.9'
43
43
  # pry-byebug can have issues with native readline libs so add rb-readline
44
44
  s.add_runtime_dependency 'rb-readline', '~> 0.5.3'
45
45
 
46
46
  s.add_runtime_dependency 'hocon', '~> 1.0'
47
47
  s.add_runtime_dependency 'net-ssh', '>= 5.0'
48
- s.add_runtime_dependency 'net-scp', '~> 1.2'
48
+ s.add_runtime_dependency 'net-scp', '>= 1.2', '< 4.0'
49
49
  s.add_runtime_dependency 'inifile', '~> 3.0'
50
50
 
51
51
  s.add_runtime_dependency 'rsync', '~> 1.0.9'
@@ -6,7 +6,7 @@ require 'rsync'
6
6
  require 'beaker/dsl/helpers'
7
7
  require 'beaker/dsl/patterns'
8
8
 
9
- [ 'command', 'ssh_connection'].each do |lib|
9
+ [ 'command', 'ssh_connection', 'local_connection' ].each do |lib|
10
10
  require "beaker/#{lib}"
11
11
  end
12
12
 
@@ -19,6 +19,7 @@ module Beaker
19
19
 
20
20
  class CommandFailure < StandardError; end
21
21
  class RebootFailure < CommandFailure; end
22
+ class RebootWarning < StandardError; end
22
23
 
23
24
  # This class provides array syntax for using puppet --configprint on a host
24
25
  class PuppetConfigReader
@@ -294,6 +295,11 @@ module Beaker
294
295
 
295
296
  def connection
296
297
  # create new connection object if necessary
298
+ if self['hypervisor'] == 'none' && @name == 'localhost'
299
+ @connection ||= LocalConnection.connect( { :ssh_env_file => self['ssh_env_file'], :logger => @logger })
300
+ return @connection
301
+ end
302
+
297
303
  @connection ||= SshConnection.connect( { :ip => self['ip'], :vmhostname => self['vmhostname'], :hostname => @name },
298
304
  self['user'],
299
305
  self['ssh'], { :logger => @logger, :ssh_connection_preference => self[:ssh_connection_preference]} )
@@ -22,7 +22,7 @@ module PSWindows::Exec
22
22
  def rm_rf path
23
23
  # ensure that we have the right slashes for windows
24
24
  path = path.gsub(/\//, '\\')
25
- execute("del /s /q #{path}")
25
+ execute(%(del /s /q "#{path}"))
26
26
  end
27
27
 
28
28
  # Move the origin to destination. The destination is removed prior to moving.
@@ -14,52 +14,101 @@ module Unix::Exec
14
14
  def reboot(wait_time=10, max_connection_tries=9, uptime_retries=18)
15
15
  require 'time'
16
16
 
17
+ attempts = 0
18
+
19
+ # Some systems don't support 'last -F reboot' but it has second granularity
20
+ boot_time_cmd = 'last -F reboot || who -b'
21
+
22
+ # Try to match all of the common formats for 'last' and 'who'
23
+ current_year = Time.now.strftime("%Y")
24
+ boot_time_regex = Regexp.new(%{((?:#{(Date::ABBR_DAYNAMES + Date::ABBR_MONTHNAMES).compact.join('|')}|#{current_year}).+?(\\d+:\\d+)+?(?::(\\d+).+?#{current_year})?)})
25
+
26
+ original_boot_time_str = nil
27
+ original_boot_time_line = nil
17
28
  begin
18
- original_boot_time_str = exec(Beaker::Command.new('who -b'), {:max_connection_tries => max_connection_tries, :silent => true}).stdout
29
+ attempts += 1
30
+ # Number of seconds to sleep before rebooting.
31
+ reboot_sleep = 1
32
+
33
+ original_boot_time_str = exec(Beaker::Command.new(boot_time_cmd), {:max_connection_tries => max_connection_tries, :silent => true}).stdout
19
34
  original_boot_time_line = original_boot_time_str.lines.grep(/boot/).first
20
35
 
21
- raise Beaker::Host::RebootFailure, "Could not find system boot time using 'who -b': #{original_boot_time_str}" unless original_boot_time_line
36
+ raise Beaker::Host::RebootWarning, "Could not find system boot time using '#{boot_time_cmd}': '#{original_boot_time_str}'" unless original_boot_time_line
37
+
38
+ original_boot_time_matches = original_boot_time_line.scan(boot_time_regex).last
39
+
40
+ raise Beaker::Host::RebootWarning, "Found no valid times in '#{original_boot_time_line}'" unless original_boot_time_matches
41
+
42
+ original_boot_time = Time.parse(original_boot_time_matches.first)
43
+
44
+ unless original_boot_time_matches.last
45
+ reboot_sleep = (61 - Time.now.strftime("%S").to_i)
46
+ end
47
+
48
+ @logger.notify("Sleeping #{reboot_sleep} seconds before rebooting")
22
49
 
23
- original_boot_time = Time.parse(original_boot_time_line)
50
+ sleep(reboot_sleep)
24
51
 
25
52
  exec(Beaker::Command.new('/bin/systemctl reboot -i || reboot || /sbin/shutdown -r now'), :expect_connection_failure => true)
26
- rescue Beaker::Host::CommandFailure => e
27
- raise Beaker::Host::RebootFailure, "Command failed when attempting to reboot: #{e.message}"
28
- rescue RuntimeError => e
29
- raise Beaker::Host::RebootFailure, "Unexpected exception in reboot: #{e.message}"
30
53
  rescue ArgumentError => e
31
54
  raise Beaker::Host::RebootFailure, "Unable to parse time: #{e.message}"
55
+ rescue Beaker::Host::RebootWarning => e
56
+ raise if attempts > uptime_retries
57
+ @logger.warn(e.message)
58
+ @logger.warn("Retrying #{uptime_retries - attempts} more times.")
59
+ retry
60
+ rescue StandardError => e
61
+ raise if attempts > uptime_retries
62
+ @logger.warn("Unexpected Exception: #{e.message}")
63
+ @logger.warn("Retrying #{uptime_retries - attempts} more times.")
64
+ @logger.warn(e.backtrace[0,3].join("\n"))
65
+ @logger.debug(e.backtrace.join("\n"))
66
+ retry
32
67
  end
33
68
 
34
69
  attempts = 0
35
70
  begin
71
+ attempts += 1
72
+
36
73
  # give the host a little time to shutdown
37
74
  @logger.debug("Waiting #{wait_time} for host to shut down.")
38
75
  sleep wait_time
39
76
 
40
- current_boot_time_str = exec(Beaker::Command.new('who -b'), {:max_connection_tries => max_connection_tries, :silent => true}).stdout
41
- current_boot_time = Time.parse(current_boot_time_str.lines.grep(/boot/).first)
77
+ # Accept all exit codes because this may fail due to the parallel nature of systemd
78
+ current_boot_time_str = exec(Beaker::Command.new(boot_time_cmd), {:max_connection_tries => max_connection_tries, :silent => true, :accept_all_exit_codes => true}).stdout
79
+ current_boot_time_line = current_boot_time_str.lines.grep(/boot/).first
80
+
81
+ raise Beaker::Host::RebootWarning, "Could not find system boot time using '#{boot_time_cmd}': '#{current_boot_time_str}'" unless current_boot_time_line
82
+
83
+ current_boot_time_matches = current_boot_time_line.scan(boot_time_regex).last
84
+
85
+ raise Beaker::Host::RebootWarning, "Found no valid times in '#{current_boot_time_line}'" unless current_boot_time_matches
86
+
87
+ current_boot_time = Time.parse(current_boot_time_matches.first)
42
88
 
43
89
  @logger.debug("Original Boot Time: #{original_boot_time}")
44
90
  @logger.debug("Current Boot Time: #{current_boot_time}")
45
91
 
46
- unless current_boot_time > original_boot_time
92
+ # If this is *exactly* the same then there is really no good way to detect a reboot
93
+ if current_boot_time == original_boot_time
47
94
  raise Beaker::Host::RebootFailure, "Boot time did not reset. Reboot appears to have failed."
48
95
  end
49
- rescue Beaker::Host::RebootFailure => e
50
- attempts += 1
51
- if attempts < uptime_retries
52
- @logger.debug("Boot time did not reset. Will retry #{uptime_retries - attempts} more times.")
53
- retry
54
- else
55
- raise
56
- end
57
- rescue Beaker::Host::CommandFailure => e
58
- raise Beaker::Host::RebootFailure, "Command failed when attempting to reboot: #{e.message}"
59
- rescue RuntimeError => e
60
- raise Beaker::Host::RebootFailure, "Unexpected exception in reboot: #{e.message}"
61
96
  rescue ArgumentError => e
62
97
  raise Beaker::Host::RebootFailure, "Unable to parse time: #{e.message}"
98
+ rescue Beaker::Host::RebootFailure => e
99
+ raise
100
+ rescue Beaker::Host::RebootWarning => e
101
+ raise if attempts > uptime_retries
102
+ @logger.warn(e.message)
103
+ @logger.warn("Retrying #{uptime_retries - attempts} more times.")
104
+ retry
105
+ rescue StandardError => e
106
+ raise if attempts > uptime_retries
107
+ @logger.warn("Unexpected Exception: #{e.message}")
108
+ @logger.warn("Retrying #{uptime_retries - attempts} more times.")
109
+ @logger.warn(e.backtrace[0,3].join("\n"))
110
+ @logger.debug(e.backtrace.join("\n"))
111
+ retry
63
112
  end
64
113
  end
65
114