beaker-vmware 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,35 +1,34 @@
1
- # -*- encoding: utf-8 -*-
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 = "beaker-vmware"
5
+ s.name = 'beaker-vmware'
7
6
  s.version = BeakerVmware::VERSION
8
- s.authors = ["Vox Pupuli"]
9
- s.email = ["voxpupuli@groups.io"]
10
- s.homepage = "https://github.com/voxpupuli/beaker-vmware"
11
- s.summary = %q{Beaker DSL Extension Helpers!}
12
- s.description = %q{For use for the Beaker acceptance testing tool}
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.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
- s.require_paths = ["lib"]
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
- s.add_development_dependency 'fakefs', '~> 0.6'
24
- s.add_development_dependency 'rake'
25
-
26
- # Documentation dependencies
27
- s.add_development_dependency 'yard'
28
- s.add_development_dependency 'markdown'
29
- s.add_development_dependency 'thin'
30
-
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'
31
29
  # Run time dependencies
32
- s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
30
+ s.add_runtime_dependency 'beaker', '>= 4', '< 6'
33
31
  s.add_runtime_dependency 'fission', '~> 0.4'
34
- s.add_runtime_dependency 'rbvmomi', '~> 1.9'
32
+ s.add_runtime_dependency 'rbvmomi', '>= 1.9', '< 4.0'
33
+ s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
35
34
  end
data/bin/beaker-vmware CHANGED
@@ -4,7 +4,7 @@ require 'rubygems' unless defined?(Gem)
4
4
  require 'beaker-vmware'
5
5
 
6
6
  VERSION_STRING =
7
- "
7
+ "
8
8
  _ .--.
9
9
  ( ` )
10
10
  beaker-vmware .-' `--,
@@ -25,8 +25,6 @@ VERSION_STRING =
25
25
  '=='
26
26
  "
27
27
 
28
-
29
-
30
28
  puts BeakerVmware::VERSION
31
29
 
32
30
  exit 0
@@ -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 "Unable to load fission, please ensure it is installed!"
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
- raise "You must specify a snapshot for Fusion instances, no snapshot defined for #{host.name}!" unless host["snapshot"]
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["vmname"] || host.name
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["snapshot"]
38
- raise "Could not find snapshot '#{snap_name}' for host #{host.name}!" unless vm.snapshots.data.include? snap_name
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 "Spent %.2f seconds reverting" % time
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 :headless => true
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 "Spent %.2f seconds resuming VM" % time
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
- " with credentials for #{vsphere_credentials[:user]}"
16
+ " with credentials for #{vsphere_credentials[:user]}"
18
17
 
19
- vsphere_helper = VsphereHelper.new( vsphere_credentials )
18
+ vsphere_helper = VsphereHelper.new(vsphere_credentials)
20
19
 
21
20
  vsphere_vms = {}
22
21
  @hosts.each do |h|
23
- name = h["vmname"] || h.name
24
- vsphere_vms[name] = h["snapshot"]
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 "Spent %.2f seconds reverting" % time
42
+ @logger.notify 'Spent %.2f seconds reverting' % time
44
43
  end
45
44
 
46
- unless vm.runtime.powerState == "poweredOn"
47
- @logger.notify "Booting #{vm.name}"
48
- start = Time.now
49
- vm.PowerOnVM_Task.wait_for_completion
50
- @logger.notify "Spent %.2f seconds booting #{vm.name}" % (Time.now - start)
51
- end
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 "Destroying vsphere boxes"
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
- " with credentials for #{vsphere_credentials[:user]}"
61
+ " with credentials for #{vsphere_credentials[:user]}"
63
62
 
64
- vsphere_helper = VsphereHelper.new( vsphere_credentials )
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
- if vm.runtime.powerState == "poweredOn"
74
- @logger.notify "Shutting down #{vm.name}"
75
- start = Time.now
76
- vm.PowerOffVM_Task.wait_for_completion
77
- @logger.notify(
78
- "Spent %.2f seconds halting #{vm.name}" % (Time.now - start) )
79
- end
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
@@ -3,12 +3,12 @@ require 'rbvmomi'
3
3
  require 'beaker/logger'
4
4
 
5
5
  class VsphereHelper
6
- def initialize vInfo
6
+ def initialize(vInfo)
7
7
  @logger = vInfo[:logger] || Beaker::Logger.new
8
- @connection = RbVmomi::VIM.connect :host => vInfo[:server],
9
- :user => vInfo[:user],
10
- :password => vInfo[:pass],
11
- :insecure => true
8
+ @connection = RbVmomi::VIM.connect host: vInfo[:server],
9
+ user: vInfo[:user],
10
+ password: vInfo[:pass],
11
+ insecure: true
12
12
  end
13
13
 
14
14
  def self.load_config(dot_fog = '.fog')
@@ -19,121 +19,121 @@ class VsphereHelper
19
19
  vsphere_credentials[:user] = default[:vsphere_username]
20
20
  vsphere_credentials[:pass] = default[:vsphere_password]
21
21
 
22
- return vsphere_credentials
22
+ vsphere_credentials
23
23
  end
24
24
 
25
- def find_snapshot vm, snapname
26
- if vm.snapshot
27
- search_child_snaps vm.snapshot.rootSnapshotList, snapname
28
- else
29
- raise "vm #{vm.name} has no snapshots to revert to"
30
- end
25
+ def find_snapshot(vm, snapname)
26
+ raise "vm #{vm.name} has no snapshots to revert to" unless vm.snapshot
27
+
28
+ search_child_snaps vm.snapshot.rootSnapshotList, snapname
31
29
  end
32
30
 
33
- def search_child_snaps tree, snapname
31
+ def search_child_snaps(tree, snapname)
34
32
  snapshot = nil
35
33
  tree.each do |child|
36
- if child.name == snapname
37
- snapshot ||= child.snapshot
38
- else
39
- snapshot ||= search_child_snaps child.childSnapshotList, snapname
40
- end
34
+ snapshot ||= if child.name == snapname
35
+ child.snapshot
36
+ else
37
+ search_child_snaps child.childSnapshotList, snapname
38
+ end
41
39
  end
42
40
  snapshot
43
41
  end
44
42
 
45
- def find_customization name
43
+ def find_customization(name)
46
44
  csm = @connection.serviceContent.customizationSpecManager
47
45
 
48
46
  begin
49
- customizationSpec = csm.GetCustomizationSpec({:name => name}).spec
50
- rescue
47
+ customizationSpec = csm.GetCustomizationSpec({ name: name }).spec
48
+ rescue StandardError
51
49
  customizationSpec = nil
52
50
  end
53
51
 
54
- return customizationSpec
52
+ customizationSpec
55
53
  end
56
54
 
57
55
  # an easier wrapper around the horrid PropertyCollector interface,
58
56
  # necessary for searching VMs in all Datacenters that may be nested
59
57
  # within folders of arbitrary depth
60
58
  # returns a hash array of <name> => <VirtualMachine ManagedObjects>
61
- def find_vms names, connection = @connection
62
- names = names.is_a?(Array) ? names : [ names ]
59
+ def find_vms(names, connection = @connection)
60
+ names = [names] unless names.is_a?(Array)
63
61
  containerView = get_base_vm_container_from connection
64
62
  propertyCollector = connection.propertyCollector
65
63
 
66
64
  objectSet = [{
67
- :obj => containerView,
68
- :skip => true,
69
- :selectSet => [ RbVmomi::VIM::TraversalSpec.new({
70
- :name => 'gettingTheVMs',
71
- :path => 'view',
72
- :skip => false,
73
- :type => 'ContainerView'
74
- }) ]
65
+ obj: containerView,
66
+ skip: true,
67
+ selectSet: [RbVmomi::VIM::TraversalSpec.new({
68
+ name: 'gettingTheVMs',
69
+ path: 'view',
70
+ skip: false,
71
+ type: 'ContainerView',
72
+ })],
75
73
  }]
76
74
 
77
75
  propSet = [{
78
- :pathSet => [ 'name' ],
79
- :type => 'VirtualMachine'
76
+ pathSet: ['name'],
77
+ type: 'VirtualMachine',
80
78
  }]
81
79
 
82
80
  results = propertyCollector.RetrievePropertiesEx({
83
- :specSet => [{
84
- :objectSet => objectSet,
85
- :propSet => propSet
86
- }],
87
- :options => { :maxObjects => nil }
88
- })
81
+ specSet: [{
82
+ objectSet: objectSet,
83
+ propSet: propSet,
84
+ }],
85
+ options: { maxObjects: nil },
86
+ })
89
87
 
90
88
  vms = {}
91
89
  results.objects.each do |result|
92
90
  name = result.propSet.first.val
93
91
  next unless names.include? name
92
+
94
93
  vms[name] = result.obj
95
94
  end
96
95
 
97
- while results.token do
98
- results = propertyCollector.ContinueRetrievePropertiesEx({:token => results.token})
96
+ while results.token
97
+ results = propertyCollector.ContinueRetrievePropertiesEx({ token: results.token })
99
98
  results.objects.each do |result|
100
99
  name = result.propSet.first.val
101
100
  next unless names.include? name
101
+
102
102
  vms[name] = result.obj
103
103
  end
104
104
  end
105
105
  vms
106
106
  end
107
107
 
108
- def find_datastore(dc,datastorename)
108
+ def find_datastore(dc, datastorename)
109
109
  datacenter = @connection.serviceInstance.find_datacenter(dc)
110
110
  datacenter.find_datastore(datastorename)
111
111
  end
112
112
 
113
- def find_folder(dc,foldername)
113
+ def find_folder(dc, foldername)
114
114
  datacenter = @connection.serviceInstance.find_datacenter(dc)
115
115
  base = datacenter.vmFolder.traverse(foldername)
116
- if base != nil
117
- base
118
- else
116
+ if base.nil?
119
117
  abort "Failed to find folder #{foldername}"
118
+ else
119
+ base
120
120
  end
121
121
  end
122
122
 
123
- def find_pool(dc,poolname)
123
+ def find_pool(dc, poolname)
124
124
  datacenter = @connection.serviceInstance.find_datacenter(dc)
125
125
  base = datacenter.hostFolder
126
126
  pools = poolname.split('/')
127
127
  pools.each do |pool|
128
128
  case base
129
- when RbVmomi::VIM::Folder
130
- base = base.childEntity.find { |f| f.name == pool }
131
- when RbVmomi::VIM::ClusterComputeResource
132
- base = base.resourcePool.resourcePool.find { |f| f.name == pool }
133
- when RbVmomi::VIM::ResourcePool
134
- base = base.resourcePool.find { |f| f.name == pool }
135
- else
136
- abort "Unexpected object type encountered (#{base.class}) while finding resource pool"
129
+ when RbVmomi::VIM::Folder
130
+ base = base.childEntity.find { |f| f.name == pool }
131
+ when RbVmomi::VIM::ClusterComputeResource
132
+ base = base.resourcePool.resourcePool.find { |f| f.name == pool }
133
+ when RbVmomi::VIM::ResourcePool
134
+ base = base.resourcePool.find { |f| f.name == pool }
135
+ else
136
+ abort "Unexpected object type encountered (#{base.class}) while finding resource pool"
137
137
  end
138
138
  end
139
139
 
@@ -141,43 +141,41 @@ class VsphereHelper
141
141
  base
142
142
  end
143
143
 
144
- def get_base_vm_container_from connection
144
+ def get_base_vm_container_from(connection)
145
145
  viewManager = connection.serviceContent.viewManager
146
146
  viewManager.CreateContainerView({
147
- :container => connection.serviceContent.rootFolder,
148
- :recursive => true,
149
- :type => [ 'VirtualMachine' ]
150
- })
147
+ container: connection.serviceContent.rootFolder,
148
+ recursive: true,
149
+ type: ['VirtualMachine'],
150
+ })
151
151
  end
152
152
 
153
- def wait_for_tasks tasks, try, attempts
154
- obj_set = tasks.map { |task| { :obj => task } }
153
+ def wait_for_tasks(tasks, try, attempts)
154
+ obj_set = tasks.map { |task| { obj: task } }
155
155
  filter = @connection.propertyCollector.CreateFilter(
156
- :spec => {
157
- :propSet => [{ :type => 'Task',
158
- :all => false,
159
- :pathSet => ['info.state']}],
160
- :objectSet => obj_set
156
+ spec: {
157
+ propSet: [{ type: 'Task',
158
+ all: false,
159
+ pathSet: ['info.state'], }],
160
+ objectSet: obj_set,
161
161
  },
162
- :partialUpdates => false
162
+ partialUpdates: false,
163
163
  )
164
164
  ver = ''
165
165
  while true
166
- result = @connection.propertyCollector.WaitForUpdates(:version => ver)
166
+ result = @connection.propertyCollector.WaitForUpdates(version: ver)
167
167
  ver = result.version
168
168
  complete = 0
169
169
  tasks.each do |task|
170
- if ['success', 'error'].member? task.info.state
171
- complete += 1
172
- end
173
- end
174
- break if (complete == tasks.length)
175
- if try <= attempts
176
- sleep 5
177
- try += 1
178
- else
179
- raise "unable to complete Vsphere tasks before timeout"
170
+ complete += 1 if %w[success error].member? task.info.state
180
171
  end
172
+ break if complete == tasks.length
173
+
174
+ raise 'unable to complete Vsphere tasks before timeout' unless try <= attempts
175
+
176
+ sleep 5
177
+ try += 1
178
+
181
179
  end
182
180
 
183
181
  filter.DestroyPropertyFilter
@@ -188,4 +186,3 @@ class VsphereHelper
188
186
  @connection.close
189
187
  end
190
188
  end
191
-
@@ -1,3 +1,3 @@
1
1
  module BeakerVmware
2
- VERSION = '1.0.0'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -2,40 +2,38 @@ require 'spec_helper'
2
2
 
3
3
  module Beaker
4
4
  describe Fusion do
5
- let( :fusion ) { Beaker::Fusion.new( @hosts, make_opts ) }
6
-
7
- before :each do
8
- stub_const( "Fission::VM", true )
9
- @hosts = make_hosts()
10
- MockFission.presets( @hosts )
11
- allow_any_instance_of( Fusion ).to receive( :require ).with( 'fission' ).and_return( true )
12
- fusion.instance_variable_set( :@fission, MockFission )
5
+ let(:fusion) { Beaker::Fusion.new(@hosts, make_opts) }
6
+
7
+ before do
8
+ stub_const('Fission::VM', true)
9
+ @hosts = make_hosts
10
+ MockFission.presets(@hosts)
11
+ allow_any_instance_of(Fusion).to receive(:require).with('fission').and_return(true)
12
+ fusion.instance_variable_set(:@fission, MockFission)
13
13
  end
14
14
 
15
- it "can interoperate with the fission library to provision hosts" do
15
+ it 'can interoperate with the fission library to provision hosts' do
16
16
  fusion.provision
17
17
  end
18
18
 
19
- it "raises an error if unknown snapshot name is used" do
19
+ it 'raises an error if unknown snapshot name is used' do
20
20
  @hosts[0][:snapshot] = 'unknown'
21
- expect{ fusion.provision }.to raise_error
21
+ expect { fusion.provision }.to raise_error
22
22
  end
23
23
 
24
24
  it 'raises an error if snapshots is nil' do
25
25
  MockFissionVM.set_snapshots(nil)
26
- expect{ fusion.provision }.to raise_error(/No snapshots available/)
26
+ expect { fusion.provision }.to raise_error(/No snapshots available/)
27
27
  end
28
28
 
29
29
  it 'raises an error if snapshots are empty' do
30
30
  MockFissionVM.set_snapshots([])
31
- expect{ fusion.provision }.to raise_error(/No snapshots available/)
31
+ expect { fusion.provision }.to raise_error(/No snapshots available/)
32
32
  end
33
33
 
34
34
  it 'host fails init with nil snapshot' do
35
35
  @hosts[0][:snapshot] = nil
36
- expect{ Beaker::Fusion.new( @hosts, make_opts) }.to raise_error(/specify a snapshot/)
36
+ expect { Beaker::Fusion.new(@hosts, make_opts) }.to raise_error(/specify a snapshot/)
37
37
  end
38
-
39
38
  end
40
-
41
39
  end