beaker-vcloud 1.1.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.
data/bin/beaker-vcloud CHANGED
@@ -4,7 +4,7 @@ require 'rubygems' unless defined?(Gem)
4
4
  require 'beaker-vcloud'
5
5
 
6
6
  VERSION_STRING =
7
- "
7
+ "
8
8
  _ .--.
9
9
  ( ` )
10
10
  beaker-vcloud .-' `--,
@@ -25,8 +25,6 @@ VERSION_STRING =
25
25
  '=='
26
26
  "
27
27
 
28
-
29
-
30
28
  puts BeakerVcloud::VERSION
31
29
 
32
30
  exit 0
@@ -4,13 +4,12 @@ require 'rbvmomi'
4
4
 
5
5
  module Beaker
6
6
  class Vcloud < Beaker::Hypervisor
7
-
8
7
  def self.new(vcloud_hosts, options)
9
8
  # Warning for pre-vmpooler style hosts configuration. TODO: remove this eventually.
10
9
  if options['pooling_api'] && !options['datacenter']
11
- options[:logger].warn "It looks like you may be trying to access vmpooler with `hypervisor: vcloud`. "\
12
- "This functionality has been removed. Change your hosts to `hypervisor: vmpooler` "\
13
- "and remove unused :datacenter, :folder, and :datastore from CONFIG."
10
+ options[:logger].warn 'It looks like you may be trying to access vmpooler with `hypervisor: vcloud`. ' \
11
+ 'This functionality has been removed. Change your hosts to `hypervisor: vmpooler` ' \
12
+ 'and remove unused :datacenter, :folder, and :datastore from CONFIG.'
14
13
  end
15
14
  super
16
15
  end
@@ -23,76 +22,71 @@ module Beaker
23
22
  raise 'You must specify a datastore for vCloud instances!' unless @options['datastore']
24
23
  raise 'You must specify a folder for vCloud instances!' unless @options['folder']
25
24
  raise 'You must specify a datacenter for vCloud instances!' unless @options['datacenter']
25
+
26
26
  @vcenter_credentials = get_fog_credentials(@options[:dot_fog], @options[:vcenter_instance] || :default)
27
27
  end
28
28
 
29
29
  def connect_to_vsphere
30
30
  @logger.notify "Connecting to vSphere at #{@vcenter_credentials[:vsphere_server]}" +
31
- " with credentials for #{@vcenter_credentials[:vsphere_username]}"
31
+ " with credentials for #{@vcenter_credentials[:vsphere_username]}"
32
32
 
33
- @vsphere_helper = VsphereHelper.new :server => @vcenter_credentials[:vsphere_server],
34
- :user => @vcenter_credentials[:vsphere_username],
35
- :pass => @vcenter_credentials[:vsphere_password]
33
+ @vsphere_helper = VsphereHelper.new server: @vcenter_credentials[:vsphere_server],
34
+ user: @vcenter_credentials[:vsphere_username],
35
+ pass: @vcenter_credentials[:vsphere_password]
36
36
  end
37
37
 
38
- def wait_for_dns_resolution host, try, attempts
38
+ def wait_for_dns_resolution(host, try, attempts)
39
39
  @logger.notify "Waiting for #{host['vmhostname']} DNS resolution"
40
40
  begin
41
41
  Socket.getaddrinfo(host['vmhostname'], nil)
42
- rescue
43
- if try <= attempts
44
- sleep 5
45
- try += 1
42
+ rescue StandardError
43
+ raise "DNS resolution failed after #{@options[:timeout].to_i} seconds" unless try <= attempts
46
44
 
47
- retry
48
- else
49
- raise "DNS resolution failed after #{@options[:timeout].to_i} seconds"
50
- end
45
+ sleep 5
46
+ try += 1
47
+
48
+ retry
51
49
  end
52
50
  end
53
51
 
54
- def booting_host host, try, attempts
52
+ def booting_host(host, try, attempts)
55
53
  @logger.notify "Booting #{host['vmhostname']} (#{host.name}) and waiting for it to register with vSphere"
56
- until
57
- @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.toolsRunningStatus == 'guestToolsRunning' and
58
- @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress != nil
59
- if try <= attempts
60
- sleep 5
61
- try += 1
62
- else
63
- raise "vSphere registration failed after #{@options[:timeout].to_i} seconds"
64
- end
54
+ until @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.toolsRunningStatus == 'guestToolsRunning' and
55
+ !@vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress.nil?
56
+ raise "vSphere registration failed after #{@options[:timeout].to_i} seconds" unless try <= attempts
57
+
58
+ sleep 5
59
+ try += 1
60
+
65
61
  end
66
62
  end
67
63
 
68
64
  # Directly borrowed from openstack hypervisor
69
65
  def enable_root(host)
70
- if host['user'] != 'root'
71
- copy_ssh_to_root(host, @options)
72
- enable_root_login(host, @options)
73
- host['user'] = 'root'
74
- host.close
75
- end
66
+ return unless host['user'] != 'root'
67
+
68
+ copy_ssh_to_root(host, @options)
69
+ enable_root_login(host, @options)
70
+ host['user'] = 'root'
71
+ host.close
76
72
  end
77
73
 
78
- def create_clone_spec host
74
+ def create_clone_spec(host)
79
75
  # Add VM annotation
80
76
  configSpec = RbVmomi::VIM.VirtualMachineConfigSpec(
81
- :annotation =>
82
- 'Base template: ' + host['template'] + "\n" +
83
- 'Creation time: ' + Time.now.strftime("%Y-%m-%d %H:%M") + "\n\n" +
84
- 'CI build link: ' + ( ENV['BUILD_URL'] || 'Deployed independently of CI' ) +
77
+ annotation: 'Base template: ' + host['template'] + "\n" +
78
+ 'Creation time: ' + Time.now.strftime('%Y-%m-%d %H:%M') + "\n\n" +
79
+ 'CI build link: ' + (ENV['BUILD_URL'] || 'Deployed independently of CI') +
85
80
  'department: ' + @options[:department] +
86
81
  'project: ' + @options[:project],
87
- :extraConfig => [
88
- { :key => 'guestinfo.hostname',
89
- :value => host['vmhostname']
90
- }
91
- ]
82
+ extraConfig: [
83
+ { key: 'guestinfo.hostname',
84
+ value: host['vmhostname'], },
85
+ ],
92
86
  )
93
87
 
94
88
  # Are we using a customization spec?
95
- customizationSpec = @vsphere_helper.find_customization( host['template'] )
89
+ customizationSpec = @vsphere_helper.find_customization(host['template'])
96
90
 
97
91
  if customizationSpec
98
92
  # Print a logger message if using a customization spec
@@ -101,45 +95,44 @@ module Beaker
101
95
 
102
96
  # Put the VM in the specified folder and resource pool
103
97
  relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec(
104
- :datastore => @vsphere_helper.find_datastore(@options['datacenter'],@options['datastore']),
105
- :pool => @options['resourcepool'] ? @vsphere_helper.find_pool(@options['datacenter'],@options['resourcepool']) : nil,
106
- :diskMoveType => :moveChildMostDiskBacking
98
+ datastore: @vsphere_helper.find_datastore(@options['datacenter'], @options['datastore']),
99
+ pool: if @options['resourcepool']
100
+ @vsphere_helper.find_pool(@options['datacenter'],
101
+ @options['resourcepool'])
102
+ end,
103
+ diskMoveType: :moveChildMostDiskBacking,
107
104
  )
108
105
 
109
106
  # Create a clone spec
110
- spec = RbVmomi::VIM.VirtualMachineCloneSpec(
111
- :config => configSpec,
112
- :location => relocateSpec,
113
- :customization => customizationSpec,
114
- :powerOn => true,
115
- :template => false
107
+ RbVmomi::VIM.VirtualMachineCloneSpec(
108
+ config: configSpec,
109
+ location: relocateSpec,
110
+ customization: customizationSpec,
111
+ powerOn: true,
112
+ template: false,
116
113
  )
117
- spec
118
114
  end
119
115
 
120
116
  def provision
121
117
  connect_to_vsphere
122
118
  begin
123
-
124
119
  try = 1
125
120
  attempts = @options[:timeout].to_i / 5
126
121
 
127
122
  start = Time.now
128
123
  tasks = []
129
- @hosts.each_with_index do |h, i|
130
- if h['name']
131
- h['vmhostname'] = h['name']
132
- else
133
- h['vmhostname'] = generate_host_name
134
- end
124
+ @hosts.each_with_index do |h, _i|
125
+ h['vmhostname'] = (h['name'] || generate_host_name)
135
126
 
136
- if h['template'].nil? and defined?(ENV['BEAKER_vcloud_template'])
137
- h['template'] = ENV['BEAKER_vcloud_template']
127
+ if h['template'].nil? and defined?(ENV.fetch('BEAKER_vcloud_template', nil))
128
+ h['template'] = ENV.fetch('BEAKER_vcloud_template', nil)
138
129
  end
139
130
 
140
- raise "Missing template configuration for #{h}. Set template in nodeset or set ENV[BEAKER_vcloud_template]" unless h['template']
131
+ unless h['template']
132
+ raise "Missing template configuration for #{h}. Set template in nodeset or set ENV[BEAKER_vcloud_template]"
133
+ end
141
134
 
142
- if h['template'] =~ /\//
135
+ if %r{/}.match?(h['template'])
143
136
  templatefolders = h['template'].split('/')
144
137
  h['template'] = templatefolders.pop
145
138
  end
@@ -149,60 +142,60 @@ module Beaker
149
142
  vm = {}
150
143
 
151
144
  if templatefolders
152
- vm[h['template']] = @vsphere_helper.find_folder(@options['datacenter'],templatefolders.join('/')).find(h['template'])
145
+ vm[h['template']] =
146
+ @vsphere_helper.find_folder(@options['datacenter'], templatefolders.join('/')).find(h['template'])
153
147
  else
154
148
  vm = @vsphere_helper.find_vms(h['template'])
155
149
  end
156
150
 
157
- if vm.length == 0
158
- raise "Unable to find template '#{h['template']}'!"
159
- end
151
+ raise "Unable to find template '#{h['template']}'!" if vm.length == 0
160
152
 
161
153
  spec = create_clone_spec(h)
162
154
 
163
155
  # Deploy from specified template
164
- tasks << vm[h['template']].CloneVM_Task( :folder => @vsphere_helper.find_folder(@options['datacenter'],@options['folder']), :name => h['vmhostname'], :spec => spec )
156
+ tasks << vm[h['template']].CloneVM_Task(
157
+ folder: @vsphere_helper.find_folder(@options['datacenter'],
158
+ @options['folder']), name: h['vmhostname'], spec: spec
159
+ )
165
160
  end
166
161
 
167
162
  try = (Time.now - start) / 5
168
163
  @vsphere_helper.wait_for_tasks(tasks, try, attempts)
169
- @logger.notify 'Spent %.2f seconds deploying VMs' % (Time.now - start)
164
+ @logger.notify format('Spent %.2f seconds deploying VMs', (Time.now - start))
170
165
 
171
166
  try = (Time.now - start) / 5
172
167
  duration = run_and_report_duration do
173
- @hosts.each_with_index do |h, i|
168
+ @hosts.each_with_index do |h, _i|
174
169
  booting_host(h, try, attempts)
175
170
  end
176
171
  end
177
- @logger.notify "Spent %.2f seconds booting and waiting for vSphere registration" % duration
172
+ @logger.notify 'Spent %.2f seconds booting and waiting for vSphere registration' % duration
178
173
 
179
174
  try = (Time.now - start) / 5
180
175
  duration = run_and_report_duration do
181
176
  @hosts.each do |host|
182
177
  repeat_fibonacci_style_for 8 do
183
- @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress != nil
178
+ !@vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress.nil?
184
179
  end
185
180
  host[:ip] = @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress
186
181
  enable_root(host) unless host.is_cygwin?
187
182
  end
188
183
  end
189
184
 
190
- @logger.notify "Spent %.2f seconds waiting for DNS resolution" % duration
191
-
192
- rescue => e
185
+ @logger.notify 'Spent %.2f seconds waiting for DNS resolution' % duration
186
+ rescue StandardError => e
193
187
  @vsphere_helper.close
194
- report_and_raise(@logger, e, "Vcloud.provision")
188
+ report_and_raise(@logger, e, 'Vcloud.provision')
195
189
  end
196
-
197
190
  end
198
191
 
199
192
  def cleanup
200
- @logger.notify "Destroying vCloud boxes"
193
+ @logger.notify 'Destroying vCloud boxes'
201
194
  connect_to_vsphere
202
195
 
203
- vm_names = @hosts.map {|h| h['vmhostname'] }.compact
196
+ vm_names = @hosts.map { |h| h['vmhostname'] }.compact
204
197
  if @hosts.length != vm_names.length
205
- @logger.warn "Some hosts did not have vmhostname set correctly! This likely means VM provisioning was not successful"
198
+ @logger.warn 'Some hosts did not have vmhostname set correctly! This likely means VM provisioning was not successful'
206
199
  end
207
200
  vms = @vsphere_helper.find_vms vm_names
208
201
  begin
@@ -224,12 +217,11 @@ module Beaker
224
217
  vm.Destroy_Task
225
218
  end
226
219
  @logger.notify "Spent %.2f seconds destroying #{vm.name}" % duration
227
-
228
220
  end
229
- rescue RbVmomi::Fault => ex
230
- if ex.fault.is_a?(RbVmomi::VIM::ManagedObjectNotFound)
231
- #it's already gone, don't bother trying to delete it
232
- name = vms.key(ex.fault.obj)
221
+ rescue RbVmomi::Fault => e
222
+ if e.fault.is_a?(RbVmomi::VIM::ManagedObjectNotFound)
223
+ # it's already gone, don't bother trying to delete it
224
+ name = vms.key(e.fault.obj)
233
225
  vms.delete(name)
234
226
  vm_names.delete(name)
235
227
  @logger.warn "Unable to destroy #{name}, it was not found in vSphere"
@@ -238,6 +230,5 @@ module Beaker
238
230
  end
239
231
  @vsphere_helper.close
240
232
  end
241
-
242
233
  end
243
234
  end
@@ -1,3 +1,3 @@
1
1
  module BeakerVcloud
2
- VERSION = '1.1.0'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -2,43 +2,41 @@ require 'spec_helper'
2
2
 
3
3
  module Beaker
4
4
  describe Vcloud do
5
-
6
- before :each do
7
- MockVsphereHelper.set_config( fog_file_contents )
8
- MockVsphereHelper.set_vms( make_hosts() )
9
- stub_const( "VsphereHelper", MockVsphereHelper )
10
- stub_const( "Net", MockNet )
11
- json = double( 'json' )
12
- allow( json ).to receive( :parse ) do |arg|
5
+ before do
6
+ MockVsphereHelper.set_config(fog_file_contents)
7
+ MockVsphereHelper.set_vms(make_hosts)
8
+ stub_const('VsphereHelper', MockVsphereHelper)
9
+ stub_const('Net', MockNet)
10
+ json = double('json')
11
+ allow(json).to receive(:parse) do |arg|
13
12
  arg
14
13
  end
15
- stub_const( "JSON", json )
16
- allow( Socket ).to receive( :getaddrinfo ).and_return( true )
17
- allow_any_instance_of( Beaker::Shared ).to receive( :get_fog_credentials ).and_return( fog_file_contents )
18
- allow_any_instance_of( VsphereHelper ).to receive( :new ).and_return (MockVsphereHelper)
14
+ stub_const('JSON', json)
15
+ allow(Socket).to receive(:getaddrinfo).and_return(true)
16
+ allow_any_instance_of(Beaker::Shared).to receive(:get_fog_credentials).and_return(fog_file_contents)
17
+ allow_any_instance_of(VsphereHelper).to receive(:new).and_return(MockVsphereHelper)
19
18
  end
20
19
 
21
- describe "#provision" do
22
-
20
+ describe '#provision' do
23
21
  it 'warns about deprecated behavior if pooling_api is provided' do
24
22
  opts = make_opts
25
23
  opts[:pooling_api] = 'testpool'
26
- expect( opts[:logger] ).to receive( :warn ).once
27
- expect{ Beaker::Vcloud.new( make_hosts, opts ) }.to raise_error( /datacenter/ )
24
+ expect(opts[:logger]).to receive(:warn).once
25
+ expect { Beaker::Vcloud.new(make_hosts, opts) }.to raise_error(/datacenter/)
28
26
  end
29
27
 
30
28
  it 'does not instantiate vmpooler if pooling_api is provided' do
31
29
  opts = make_opts
32
30
  opts[:pooling_api] = 'testpool'
33
- expect{ Beaker::Vcloud.new( make_hosts, opts ) }.to raise_error( /datacenter/ )
31
+ expect { Beaker::Vcloud.new(make_hosts, opts) }.to raise_error(/datacenter/)
34
32
  end
35
33
 
36
34
  it 'ignores pooling_api and instantiates self' do
37
35
  opts = make_opts
38
36
  opts[:pooling_api] = 'testpool'
39
37
  opts[:datacenter] = 'testdatacenter'
40
- hypervisor = Beaker::Vcloud.new( make_hosts, opts)
41
- expect( hypervisor.class ).to be Beaker::Vcloud
38
+ hypervisor = Beaker::Vcloud.new(make_hosts, opts)
39
+ expect(hypervisor.class).to be Beaker::Vcloud
42
40
  end
43
41
 
44
42
  it 'provisions hosts and add them to the pool' do
@@ -48,18 +46,17 @@ module Beaker
48
46
  opts[:pooling_api] = nil
49
47
  opts[:datacenter] = 'testdc'
50
48
 
51
- vcloud = Beaker::Vcloud.new( make_hosts, opts )
52
- allow( vcloud ).to receive( :require ).and_return( true )
53
- allow( vcloud ).to receive( :sleep ).and_return( true )
49
+ vcloud = Beaker::Vcloud.new(make_hosts, opts)
50
+ allow(vcloud).to receive(:require).and_return(true)
51
+ allow(vcloud).to receive(:sleep).and_return(true)
54
52
  vcloud.provision
55
53
 
56
- hosts = vcloud.instance_variable_get( :@hosts )
57
- hosts.each do | host |
54
+ hosts = vcloud.instance_variable_get(:@hosts)
55
+ hosts.each do |host|
58
56
  name = host['vmhostname']
59
- vm = MockVsphereHelper.find_vm( name )
60
- expect( vm.toolsRunningStatus ).to be === "guestToolsRunning"
57
+ vm = MockVsphereHelper.find_vm(name)
58
+ expect(vm.toolsRunningStatus).to be === 'guestToolsRunning'
61
59
  end
62
-
63
60
  end
64
61
 
65
62
  it 'does not run enable_root on cygwin hosts' do
@@ -71,44 +68,37 @@ module Beaker
71
68
 
72
69
  hosts = make_hosts
73
70
  hosts.each do |host|
74
- allow( host ).to receive( :is_cygwin? ).and_return( true )
71
+ allow(host).to receive(:is_cygwin?).and_return(true)
75
72
  end
76
- vcloud = Beaker::Vcloud.new( hosts, opts )
77
- allow( vcloud ).to receive( :require ).and_return( true )
78
- allow( vcloud ).to receive( :sleep ).and_return( true )
79
- expect( vcloud ).to receive( :enable_root ).never
73
+ vcloud = Beaker::Vcloud.new(hosts, opts)
74
+ allow(vcloud).to receive(:require).and_return(true)
75
+ allow(vcloud).to receive(:sleep).and_return(true)
76
+ expect(vcloud).not_to receive(:enable_root)
80
77
  vcloud.provision
81
-
82
78
  end
83
-
84
79
  end
85
80
 
86
- describe "#cleanup" do
87
-
88
- it "cleans up hosts not in the pool" do
81
+ describe '#cleanup' do
82
+ it 'cleans up hosts not in the pool' do
89
83
  MockVsphereHelper.powerOn
90
84
 
91
85
  opts = make_opts
92
86
  opts[:pooling_api] = nil
93
87
  opts[:datacenter] = 'testdc'
94
88
 
95
- vcloud = Beaker::Vcloud.new( make_hosts, opts )
96
- allow( vcloud ).to receive( :require ).and_return( true )
97
- allow( vcloud ).to receive( :sleep ).and_return( true )
89
+ vcloud = Beaker::Vcloud.new(make_hosts, opts)
90
+ allow(vcloud).to receive(:require).and_return(true)
91
+ allow(vcloud).to receive(:sleep).and_return(true)
98
92
  vcloud.provision
99
93
  vcloud.cleanup
100
94
 
101
- hosts = vcloud.instance_variable_get( :@hosts )
102
- vm_names = hosts.map {|h| h['vmhostname'] }.compact
103
- vm_names.each do | name |
104
- vm = MockVsphereHelper.find_vm( name )
105
- expect( vm.runtime.powerState ).to be === "poweredOff"
95
+ hosts = vcloud.instance_variable_get(:@hosts)
96
+ vm_names = hosts.map { |h| h['vmhostname'] }.compact
97
+ vm_names.each do |name|
98
+ vm = MockVsphereHelper.find_vm(name)
99
+ expect(vm.runtime.powerState).to be === 'poweredOff'
106
100
  end
107
-
108
101
  end
109
-
110
102
  end
111
-
112
103
  end
113
-
114
104
  end