beaker-vmware 0.3.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/release.yml +32 -0
- data/.github/workflows/test.yml +56 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +266 -0
- data/.simplecov +1 -1
- data/CHANGELOG.md +62 -0
- data/Gemfile +6 -21
- data/README.md +43 -9
- data/Rakefile +34 -119
- data/beaker-vmware.gemspec +20 -30
- data/bin/beaker-vmware +1 -3
- data/lib/beaker/hypervisor/fusion.rb +21 -23
- data/lib/beaker/hypervisor/vsphere.rb +23 -24
- data/lib/beaker/hypervisor/vsphere_helper.rb +78 -81
- data/lib/beaker-vmware/version.rb +1 -1
- data/spec/beaker/hypervisor/fusion_spec.rb +14 -16
- data/spec/beaker/hypervisor/vsphere_helper_spec.rb +120 -124
- data/spec/beaker/hypervisor/vsphere_spec.rb +28 -40
- data/spec/mock_fission.rb +63 -0
- data/spec/mock_vsphere.rb +284 -0
- data/spec/mock_vsphere_helper.rb +167 -0
- data/spec/spec_helper.rb +28 -3
- metadata +65 -59
data/Rakefile
CHANGED
@@ -1,46 +1,39 @@
|
|
1
1
|
require 'rspec/core/rake_task'
|
2
2
|
|
3
3
|
namespace :test do
|
4
|
-
|
5
4
|
namespace :spec do
|
6
|
-
|
7
|
-
desc "Run spec tests"
|
5
|
+
desc 'Run spec tests'
|
8
6
|
RSpec::Core::RakeTask.new(:run) do |t|
|
9
7
|
t.rspec_opts = ['--color']
|
10
8
|
t.pattern = 'spec/'
|
11
9
|
end
|
12
10
|
|
13
|
-
desc
|
11
|
+
desc 'Run spec tests with coverage'
|
14
12
|
RSpec::Core::RakeTask.new(:coverage) do |t|
|
15
13
|
ENV['BEAKER_VMWARE_COVERAGE'] = 'y'
|
16
14
|
t.rspec_opts = ['--color']
|
17
15
|
t.pattern = 'spec/'
|
18
16
|
end
|
19
|
-
|
20
17
|
end
|
21
18
|
|
22
19
|
namespace :acceptance do
|
23
|
-
|
24
|
-
|
25
|
-
A quick acceptance test, named because it has no pre-suites to run
|
20
|
+
desc <<~EOS
|
21
|
+
A quick acceptance test, named because it has no pre-suites to run
|
26
22
|
EOS
|
27
23
|
task :quick do
|
28
|
-
|
29
24
|
# setup & load_path of beaker's acceptance base and lib directory
|
30
25
|
beaker_gem_spec = Gem::Specification.find_by_name('beaker')
|
31
26
|
beaker_gem_dir = beaker_gem_spec.gem_dir
|
32
27
|
beaker_test_base_dir = File.join(beaker_gem_dir, 'acceptance/tests/base')
|
33
28
|
load_path_option = File.join(beaker_gem_dir, 'acceptance/lib')
|
34
29
|
|
35
|
-
sh(
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
sh('beaker',
|
31
|
+
'--hosts', 'acceptance/config/nodes/test-nodes.yml',
|
32
|
+
'--tests', beaker_test_base_dir,
|
33
|
+
'--log-level', 'debug',
|
34
|
+
'--load-path', load_path_option)
|
40
35
|
end
|
41
|
-
|
42
36
|
end
|
43
|
-
|
44
37
|
end
|
45
38
|
|
46
39
|
# namespace-named default tasks.
|
@@ -50,111 +43,33 @@ task 'test:spec' => 'test:spec:run'
|
|
50
43
|
task 'test:acceptance' => 'test:acceptance:quick'
|
51
44
|
|
52
45
|
# global defaults
|
53
|
-
task :
|
54
|
-
task :
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
raise StandardError, "Found multiple YARD Servers. Don't know what to do."
|
46
|
+
task test: 'test:spec'
|
47
|
+
task default: :test
|
48
|
+
|
49
|
+
begin
|
50
|
+
require 'rubygems'
|
51
|
+
require 'github_changelog_generator/task'
|
52
|
+
rescue LoadError
|
53
|
+
# github_changelog_generator is an optional group
|
54
|
+
else
|
55
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
56
|
+
config.exclude_labels = %w[duplicate question invalid wontfix wont-fix skip-changelog]
|
57
|
+
config.user = 'voxpupuli'
|
58
|
+
config.project = 'beaker-vmware'
|
59
|
+
gem_version = Gem::Specification.load("#{config.project}.gemspec").version
|
60
|
+
config.future_release = gem_version
|
69
61
|
end
|
70
|
-
|
71
|
-
yes = found.empty? ? false : true
|
72
|
-
return yes, found.first
|
73
|
-
end
|
74
|
-
|
75
|
-
def pid_from( output )
|
76
|
-
output.squeeze(' ').strip.split(' ')[1]
|
77
|
-
end
|
78
|
-
|
79
|
-
desc 'Start the documentation server in the foreground'
|
80
|
-
task :docs => 'docs:clear' do
|
81
|
-
original_dir = Dir.pwd
|
82
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
83
|
-
sh FOREGROUND_SERVER
|
84
|
-
Dir.chdir( original_dir )
|
85
62
|
end
|
86
63
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
desc 'Generate static documentation'
|
98
|
-
task :gen => 'docs:clear' do
|
99
|
-
original_dir = Dir.pwd
|
100
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
101
|
-
output = `bundle exec yard doc`
|
102
|
-
puts output
|
103
|
-
if output =~ /\[warn\]|\[error\]/
|
104
|
-
fail "Errors/Warnings during yard documentation generation"
|
105
|
-
end
|
106
|
-
Dir.chdir( original_dir )
|
107
|
-
end
|
108
|
-
|
109
|
-
desc 'Run the documentation server in the background, alias `bg`'
|
110
|
-
task :background => 'docs:clear' do
|
111
|
-
yes, output = running?( DOCS_DAEMON )
|
112
|
-
if yes
|
113
|
-
puts "Not starting a new YARD Server..."
|
114
|
-
puts "Found one running with pid #{pid_from( output )}."
|
115
|
-
else
|
116
|
-
original_dir = Dir.pwd
|
117
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
118
|
-
sh "bundle exec #{DOCS_DAEMON}"
|
119
|
-
Dir.chdir( original_dir )
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
task(:bg) { Rake::Task['docs:background'].invoke }
|
124
|
-
|
125
|
-
desc 'Check the status of the documentation server'
|
126
|
-
task :status do
|
127
|
-
yes, output = running?( DOCS_DAEMON )
|
128
|
-
if yes
|
129
|
-
pid = pid_from( output )
|
130
|
-
puts "Found a YARD Server running with pid #{pid}"
|
131
|
-
else
|
132
|
-
puts "Could not find a running YARD Server."
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
desc "Stop a running YARD Server"
|
137
|
-
task :stop do
|
138
|
-
yes, output = running?( DOCS_DAEMON )
|
139
|
-
if yes
|
140
|
-
pid = pid_from( output )
|
141
|
-
puts "Found a YARD Server running with pid #{pid}"
|
142
|
-
`kill #{pid}`
|
143
|
-
puts "Stopping..."
|
144
|
-
yes, output = running?( DOCS_DAEMON )
|
145
|
-
if yes
|
146
|
-
`kill -9 #{pid}`
|
147
|
-
yes, output = running?( DOCS_DAEMON )
|
148
|
-
if yes
|
149
|
-
puts "Could not Stop Server!"
|
150
|
-
else
|
151
|
-
puts "Server stopped."
|
152
|
-
end
|
153
|
-
else
|
154
|
-
puts "Server stopped."
|
155
|
-
end
|
156
|
-
else
|
157
|
-
puts "Could not find a running YARD Server"
|
158
|
-
end
|
64
|
+
begin
|
65
|
+
require 'rubocop/rake_task'
|
66
|
+
rescue LoadError
|
67
|
+
# RuboCop is an optional group
|
68
|
+
else
|
69
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
70
|
+
# These make the rubocop experience maybe slightly less terrible
|
71
|
+
task.options = ['--display-cop-names', '--display-style-guide', '--extra-details']
|
72
|
+
# Use Rubocop's Github Actions formatter if possible
|
73
|
+
task.formatters << 'github' if ENV['GITHUB_ACTIONS'] == 'true'
|
159
74
|
end
|
160
75
|
end
|
data/beaker-vmware.gemspec
CHANGED
@@ -1,44 +1,34 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
1
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
3
2
|
require 'beaker-vmware/version'
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
5
|
+
s.name = 'beaker-vmware'
|
7
6
|
s.version = BeakerVmware::VERSION
|
8
|
-
s.authors = [
|
9
|
-
s.email = [
|
10
|
-
s.homepage =
|
11
|
-
s.summary =
|
12
|
-
s.description =
|
7
|
+
s.authors = ['Vox Pupuli']
|
8
|
+
s.email = ['voxpupuli@groups.io']
|
9
|
+
s.homepage = 'https://github.com/voxpupuli/beaker-vmware'
|
10
|
+
s.summary = 'Beaker DSL Extension Helpers!'
|
11
|
+
s.description = 'For use for the Beaker acceptance testing tool'
|
13
12
|
s.license = 'Apache2'
|
14
13
|
|
15
14
|
s.files = `git ls-files`.split("\n")
|
16
|
-
s.
|
17
|
-
s.
|
18
|
-
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
16
|
+
s.require_paths = ['lib']
|
17
|
+
|
18
|
+
s.required_ruby_version = Gem::Requirement.new('>= 2.7')
|
19
19
|
|
20
20
|
# Testing dependencies
|
21
|
+
s.add_development_dependency 'fakefs', '~> 2.4'
|
22
|
+
s.add_development_dependency 'rake'
|
21
23
|
s.add_development_dependency 'rspec', '~> 3.0'
|
22
24
|
s.add_development_dependency 'rspec-its'
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
s.add_development_dependency 'rake', '~> 10.1'
|
29
|
-
s.add_development_dependency 'simplecov'
|
30
|
-
s.add_development_dependency 'pry', '~> 0.10'
|
31
|
-
s.add_development_dependency 'beaker', '~> 3.0'
|
32
|
-
|
33
|
-
# Documentation dependencies
|
34
|
-
s.add_development_dependency 'yard'
|
35
|
-
s.add_development_dependency 'markdown'
|
36
|
-
s.add_development_dependency 'thin'
|
37
|
-
|
25
|
+
s.add_development_dependency 'rubocop', '~> 1.48.1'
|
26
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.10'
|
27
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.2'
|
28
|
+
s.add_development_dependency 'rubocop-rspec', '>= 1.44'
|
38
29
|
# Run time dependencies
|
39
|
-
s.add_runtime_dependency '
|
30
|
+
s.add_runtime_dependency 'beaker', '>= 4', '< 6'
|
40
31
|
s.add_runtime_dependency 'fission', '~> 0.4'
|
41
|
-
s.add_runtime_dependency 'rbvmomi', '
|
42
|
-
|
32
|
+
s.add_runtime_dependency 'rbvmomi', '>= 1.9', '< 4.0'
|
33
|
+
s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
|
43
34
|
end
|
44
|
-
|
data/bin/beaker-vmware
CHANGED
@@ -1,29 +1,30 @@
|
|
1
1
|
module Beaker
|
2
2
|
class Fusion < Beaker::Hypervisor
|
3
|
-
|
4
3
|
def initialize(fusion_hosts, options)
|
5
4
|
require 'rubygems' unless defined?(Gem)
|
6
5
|
begin
|
7
6
|
require 'fission'
|
8
7
|
rescue LoadError
|
9
|
-
raise
|
8
|
+
raise 'Unable to load fission, please ensure it is installed!'
|
10
9
|
end
|
11
10
|
@logger = options[:logger]
|
12
11
|
@options = options
|
13
12
|
@hosts = fusion_hosts
|
14
|
-
#check preconditions for fusion
|
13
|
+
# check preconditions for fusion
|
15
14
|
@hosts.each do |host|
|
16
|
-
|
15
|
+
unless host['snapshot']
|
16
|
+
raise "You must specify a snapshot for Fusion instances, no snapshot defined for #{host.name}!"
|
17
|
+
end
|
17
18
|
end
|
18
19
|
@fission = Fission::VM
|
19
20
|
end
|
20
21
|
|
21
22
|
def provision
|
22
|
-
available = @fission.all.data.collect{|vm| vm.name}.sort.join(
|
23
|
+
available = @fission.all.data.collect { |vm| vm.name }.sort.join(', ')
|
23
24
|
@logger.notify "Available VM names: #{available}"
|
24
25
|
|
25
26
|
@hosts.each do |host|
|
26
|
-
vm_name = host[
|
27
|
+
vm_name = host['vmname'] || host.name
|
27
28
|
vm = @fission.new vm_name
|
28
29
|
raise "Could not find VM '#{vm_name}' for #{host.name}!" unless vm.exists?
|
29
30
|
|
@@ -32,34 +33,31 @@ module Beaker
|
|
32
33
|
raise "No snapshots available for VM #{host.name} (vmname: '#{vm_name}')"
|
33
34
|
end
|
34
35
|
|
35
|
-
available_snapshots = vm_snapshots.sort.join(
|
36
|
+
available_snapshots = vm_snapshots.sort.join(', ')
|
36
37
|
@logger.notify "Available snapshots for #{host.name}: #{available_snapshots}"
|
37
|
-
snap_name = host[
|
38
|
-
|
38
|
+
snap_name = host['snapshot']
|
39
|
+
unless vm.snapshots.data.include? snap_name
|
40
|
+
raise "Could not find snapshot '#{snap_name}' for host #{host.name}!"
|
41
|
+
end
|
39
42
|
|
40
43
|
@logger.notify "Reverting #{host.name} to snapshot '#{snap_name}'"
|
41
44
|
start = Time.now
|
42
45
|
vm.revert_to_snapshot snap_name
|
43
|
-
while vm.running?.data
|
44
|
-
sleep 1
|
45
|
-
end
|
46
|
+
sleep 1 while vm.running?.data
|
46
47
|
time = Time.now - start
|
47
|
-
@logger.notify
|
48
|
+
@logger.notify 'Spent %.2f seconds reverting' % time
|
48
49
|
|
49
50
|
@logger.notify "Resuming #{host.name}"
|
50
51
|
start = Time.now
|
51
|
-
vm.start :
|
52
|
-
until vm.running?.data
|
53
|
-
sleep 1
|
54
|
-
end
|
52
|
+
vm.start headless: true
|
53
|
+
sleep 1 until vm.running?.data
|
55
54
|
time = Time.now - start
|
56
|
-
@logger.notify
|
57
|
-
end
|
58
|
-
end #revert_fusion
|
59
|
-
|
60
|
-
def cleanup
|
61
|
-
@logger.notify "No cleanup for fusion boxes"
|
55
|
+
@logger.notify 'Spent %.2f seconds resuming VM' % time
|
62
56
|
end
|
57
|
+
end # revert_fusion
|
63
58
|
|
59
|
+
def cleanup
|
60
|
+
@logger.notify 'No cleanup for fusion boxes'
|
61
|
+
end
|
64
62
|
end
|
65
63
|
end
|
@@ -3,7 +3,6 @@ require 'beaker/hypervisor/vsphere_helper'
|
|
3
3
|
|
4
4
|
module Beaker
|
5
5
|
class Vsphere < Beaker::Hypervisor
|
6
|
-
|
7
6
|
def initialize(vsphere_hosts, options)
|
8
7
|
@options = options
|
9
8
|
@logger = options[:logger]
|
@@ -14,14 +13,14 @@ module Beaker
|
|
14
13
|
vsphere_credentials = VsphereHelper.load_config(@options[:dot_fog])
|
15
14
|
|
16
15
|
@logger.notify "Connecting to vSphere at #{vsphere_credentials[:server]}" +
|
17
|
-
|
16
|
+
" with credentials for #{vsphere_credentials[:user]}"
|
18
17
|
|
19
|
-
vsphere_helper = VsphereHelper.new(
|
18
|
+
vsphere_helper = VsphereHelper.new(vsphere_credentials)
|
20
19
|
|
21
20
|
vsphere_vms = {}
|
22
21
|
@hosts.each do |h|
|
23
|
-
name = h[
|
24
|
-
vsphere_vms[name] = h[
|
22
|
+
name = h['vmname'] || h.name
|
23
|
+
vsphere_vms[name] = h['snapshot']
|
25
24
|
end
|
26
25
|
vms = vsphere_helper.find_vms(vsphere_vms.keys)
|
27
26
|
vsphere_vms.each_pair do |name, snap|
|
@@ -40,47 +39,47 @@ module Beaker
|
|
40
39
|
snapshot.RevertToSnapshot_Task.wait_for_completion
|
41
40
|
|
42
41
|
time = Time.now - start
|
43
|
-
@logger.notify
|
42
|
+
@logger.notify 'Spent %.2f seconds reverting' % time
|
44
43
|
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
next if vm.runtime.powerState == 'poweredOn'
|
46
|
+
|
47
|
+
@logger.notify "Booting #{vm.name}"
|
48
|
+
start = Time.now
|
49
|
+
vm.PowerOnVM_Task.wait_for_completion
|
50
|
+
@logger.notify format("Spent %.2f seconds booting #{vm.name}", (Time.now - start))
|
52
51
|
end
|
53
52
|
|
54
53
|
vsphere_helper.close
|
55
54
|
end
|
56
55
|
|
57
56
|
def cleanup
|
58
|
-
@logger.notify
|
57
|
+
@logger.notify 'Destroying vsphere boxes'
|
59
58
|
vsphere_credentials = VsphereHelper.load_config(@options[:dot_fog])
|
60
59
|
|
61
60
|
@logger.notify "Connecting to vSphere at #{vsphere_credentials[:server]}" +
|
62
|
-
|
61
|
+
" with credentials for #{vsphere_credentials[:user]}"
|
63
62
|
|
64
|
-
vsphere_helper = VsphereHelper.new(
|
63
|
+
vsphere_helper = VsphereHelper.new(vsphere_credentials)
|
65
64
|
|
66
|
-
vm_names = @hosts.map {|h| h['vmname'] || h.name }
|
65
|
+
vm_names = @hosts.map { |h| h['vmname'] || h.name }
|
67
66
|
vms = vsphere_helper.find_vms vm_names
|
68
67
|
vm_names.each do |name|
|
69
68
|
unless vm = vms[name]
|
70
69
|
raise "Couldn't find VM #{name} in vSphere!"
|
71
70
|
end
|
72
71
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
72
|
+
next unless vm.runtime.powerState == 'poweredOn'
|
73
|
+
|
74
|
+
@logger.notify "Shutting down #{vm.name}"
|
75
|
+
start = Time.now
|
76
|
+
vm.PowerOffVM_Task.wait_for_completion
|
77
|
+
@logger.notify(
|
78
|
+
format("Spent %.2f seconds halting #{vm.name}", (Time.now - start)),
|
79
|
+
)
|
80
80
|
end
|
81
81
|
|
82
82
|
vsphere_helper.close
|
83
83
|
end
|
84
|
-
|
85
84
|
end
|
86
85
|
end
|