beaker-vmpooler 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTM4OWFjZjExMGE1ZTAzMmRlNjEzZjRjNGE1MjFmOTc2NDc2MWM5Yw==
4
+ M2U4YmFhNjE0OTE4MzZkN2RhNWEzYWZlNGUxYjVmNjhhMGE3NDBjMQ==
5
5
  data.tar.gz: !binary |-
6
- MWE1ZjU5NDRhMmNhMmUyOTdkZjg1NjhiMDRiMGUxMWVlNDMxN2ExZA==
6
+ OTU2MjlmNjRmNzg5Zjk4YmYzZmZlZGMyZWZjMjk5YmYyMmVjYzhkNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MjE4ZDgxZjA1ZTc1ZTg2ZjllMjgxZWEwNjliNDc4MjM4MDRmMzBkYTIxM2E2
10
- MzVmNzQwZjM5MGViNDBjNzdhYzZkZjVjNDZjMzQ1MzlhZTQ1Yjg3M2FkMmJi
11
- MGQ2MWVmMzlmNWU0ZTVkZGNiNmUxZDM2YTJhYTUzOTlkM2MxMGI=
9
+ NmVjYWYxODI2NDIyYzc2YzE4ZWUzZGNlZmMyNmQyMTliYzZhZTU0MzFmYTkx
10
+ ZDNiMTVkMjFiZTQzZGQ5YjgyMGFjNDUwNjIzMzc0MWM0YWViYmExNTgwY2Mz
11
+ NWYzNTQ1NzQwMzU1Y2IxMDI0MWFiMTFlMzc1OTllYjFhMmRmNTU=
12
12
  data.tar.gz: !binary |-
13
- Nzg5YmNiOWFkOTRlODYxZGYyNzUxMTY1NmUwNGZlNDg0NGQwYmExN2E3ZTY4
14
- MDc1ZGRkNjY4MTRlNmZjYTllYzIwYjliMmFhZGI3NGMxMGQ3MTRhNWYwYWZm
15
- NzZiMDJkZTQxNDJmMWI2NGM2YWZjZjNiZWVjNTdmMGYxZDFkYWM=
13
+ OGM2ODE3YmM5OGQ2ZWRlMWI3YmIwODM2ZTEyODllNWRiODZhYzQ4NDIyYzZm
14
+ MzYwZTk0YWM4ZTJlY2VhOGI2NzI1MTZlZDczMWZhYjRlMTE4YzgzNjJkNTYz
15
+ ZjEwNGM5YjRkZTA4NDM1ODhkY2M3N2YzOTVhZjIzZDQ2MThjYmE=
@@ -32,7 +32,6 @@ Gem::Specification.new do |s|
32
32
 
33
33
  # Run time dependencies
34
34
  s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
35
- s.add_runtime_dependency 'rbvmomi', '~> 1.9'
36
35
 
37
36
  end
38
37
 
@@ -1,3 +1,3 @@
1
1
  module BeakerVmpooler
2
- VERSION = '0.2.0'
2
+ VERSION = '1.0.0'
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -2,7 +2,6 @@ require 'simplecov'
2
2
  require 'rspec/its'
3
3
  require 'beaker'
4
4
  require 'beaker/hypervisor/vmpooler'
5
- require 'beaker/hypervisor/vcloud'
6
5
 
7
6
  # setup & require beaker's spec_helper.rb
8
7
  beaker_gem_spec = Gem::Specification.find_by_name('beaker')
@@ -14,4 +13,4 @@ require File.join(beaker_spec_path, 'spec_helper.rb')
14
13
  RSpec.configure do |config|
15
14
  config.include TestFileHelpers
16
15
  config.include HostHelpers
17
- end
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker-vmpooler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rishi Javia, Kevin Imber, Tony Vu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-21 00:00:00.000000000 Z
11
+ date: 2017-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -150,20 +150,6 @@ dependencies:
150
150
  - - ~>
151
151
  - !ruby/object:Gem::Version
152
152
  version: 0.0.0
153
- - !ruby/object:Gem::Dependency
154
- name: rbvmomi
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ~>
158
- - !ruby/object:Gem::Version
159
- version: '1.9'
160
- type: :runtime
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ~>
165
- - !ruby/object:Gem::Version
166
- version: '1.9'
167
153
  description: For use for the Beaker acceptance testing tool
168
154
  email:
169
155
  - rishi.javia@puppet.com, kevin.imber@puppet.com, tony.vu@puppet.com
@@ -182,9 +168,7 @@ files:
182
168
  - beaker-vmpooler.gemspec
183
169
  - bin/beaker-vmpooler
184
170
  - lib/beaker-vmpooler/version.rb
185
- - lib/beaker/hypervisor/vcloud.rb
186
171
  - lib/beaker/hypervisor/vmpooler.rb
187
- - spec/beaker/hypervisor/vcloud_spec.rb
188
172
  - spec/beaker/hypervisor/vmpooler_spec.rb
189
173
  - spec/spec_helper.rb
190
174
  - vmpooler.md
@@ -1,238 +0,0 @@
1
- require 'yaml' unless defined?(YAML)
2
- require 'beaker/hypervisor/vmpooler'
3
-
4
- module Beaker
5
- class Vcloud < Beaker::Hypervisor
6
-
7
- def self.new(vcloud_hosts, options)
8
- if options['pooling_api']
9
- Beaker::Vmpooler.new(vcloud_hosts, options)
10
- else
11
- super
12
- end
13
- end
14
-
15
- def initialize(vcloud_hosts, options)
16
- @options = options
17
- @logger = options[:logger]
18
- @hosts = vcloud_hosts
19
-
20
- raise 'You must specify a datastore for vCloud instances!' unless @options['datastore']
21
- raise 'You must specify a folder for vCloud instances!' unless @options['folder']
22
- raise 'You must specify a datacenter for vCloud instances!' unless @options['datacenter']
23
- @vsphere_credentials = VsphereHelper.load_config(@options[:dot_fog])
24
- end
25
-
26
- def connect_to_vsphere
27
- @logger.notify "Connecting to vSphere at #{@vsphere_credentials[:server]}" +
28
- " with credentials for #{@vsphere_credentials[:user]}"
29
-
30
- @vsphere_helper = VsphereHelper.new( @vsphere_credentials )
31
- end
32
-
33
- def wait_for_dns_resolution host, try, attempts
34
- @logger.notify "Waiting for #{host['vmhostname']} DNS resolution"
35
- begin
36
- Socket.getaddrinfo(host['vmhostname'], nil)
37
- rescue
38
- if try <= attempts
39
- sleep 5
40
- try += 1
41
-
42
- retry
43
- else
44
- raise "DNS resolution failed after #{@options[:timeout].to_i} seconds"
45
- end
46
- end
47
- end
48
-
49
- def booting_host host, try, attempts
50
- @logger.notify "Booting #{host['vmhostname']} (#{host.name}) and waiting for it to register with vSphere"
51
- until
52
- @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.toolsRunningStatus == 'guestToolsRunning' and
53
- @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress != nil
54
- if try <= attempts
55
- sleep 5
56
- try += 1
57
- else
58
- raise "vSphere registration failed after #{@options[:timeout].to_i} seconds"
59
- end
60
- end
61
- end
62
-
63
- # Directly borrowed from openstack hypervisor
64
- def enable_root(host)
65
- if host['user'] != 'root'
66
- copy_ssh_to_root(host, @options)
67
- enable_root_login(host, @options)
68
- host['user'] = 'root'
69
- host.close
70
- end
71
- end
72
-
73
- def create_clone_spec host
74
- # Add VM annotation
75
- configSpec = RbVmomi::VIM.VirtualMachineConfigSpec(
76
- :annotation =>
77
- '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' ) +
80
- 'department: ' + @options[:department] +
81
- 'project: ' + @options[:project],
82
- :extraConfig => [
83
- { :key => 'guestinfo.hostname',
84
- :value => host['vmhostname']
85
- }
86
- ]
87
- )
88
-
89
- # Are we using a customization spec?
90
- customizationSpec = @vsphere_helper.find_customization( host['template'] )
91
-
92
- if customizationSpec
93
- # Print a logger message if using a customization spec
94
- @logger.notify "Found customization spec for '#{host['template']}', will apply after boot"
95
- end
96
-
97
- # Put the VM in the specified folder and resource pool
98
- relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec(
99
- :datastore => @vsphere_helper.find_datastore(@options['datacenter'],@options['datastore']),
100
- :pool => @options['resourcepool'] ? @vsphere_helper.find_pool(@options['datacenter'],@options['resourcepool']) : nil,
101
- :diskMoveType => :moveChildMostDiskBacking
102
- )
103
-
104
- # Create a clone spec
105
- spec = RbVmomi::VIM.VirtualMachineCloneSpec(
106
- :config => configSpec,
107
- :location => relocateSpec,
108
- :customization => customizationSpec,
109
- :powerOn => true,
110
- :template => false
111
- )
112
- spec
113
- end
114
-
115
- def provision
116
- connect_to_vsphere
117
- begin
118
-
119
- try = 1
120
- attempts = @options[:timeout].to_i / 5
121
-
122
- start = Time.now
123
- tasks = []
124
- @hosts.each_with_index do |h, i|
125
- if h['name']
126
- h['vmhostname'] = h['name']
127
- else
128
- h['vmhostname'] = generate_host_name
129
- end
130
-
131
- if h['template'].nil? and defined?(ENV['BEAKER_vcloud_template'])
132
- h['template'] = ENV['BEAKER_vcloud_template']
133
- end
134
-
135
- raise "Missing template configuration for #{h}. Set template in nodeset or set ENV[BEAKER_vcloud_template]" unless h['template']
136
-
137
- if h['template'] =~ /\//
138
- templatefolders = h['template'].split('/')
139
- h['template'] = templatefolders.pop
140
- end
141
-
142
- @logger.notify "Deploying #{h['vmhostname']} (#{h.name}) to #{@options['folder']} from template '#{h['template']}'"
143
-
144
- vm = {}
145
-
146
- if templatefolders
147
- vm[h['template']] = @vsphere_helper.find_folder(@options['datacenter'],templatefolders.join('/')).find(h['template'])
148
- else
149
- vm = @vsphere_helper.find_vms(h['template'])
150
- end
151
-
152
- if vm.length == 0
153
- raise "Unable to find template '#{h['template']}'!"
154
- end
155
-
156
- spec = create_clone_spec(h)
157
-
158
- # Deploy from specified template
159
- tasks << vm[h['template']].CloneVM_Task( :folder => @vsphere_helper.find_folder(@options['datacenter'],@options['folder']), :name => h['vmhostname'], :spec => spec )
160
- end
161
-
162
- try = (Time.now - start) / 5
163
- @vsphere_helper.wait_for_tasks(tasks, try, attempts)
164
- @logger.notify 'Spent %.2f seconds deploying VMs' % (Time.now - start)
165
-
166
- try = (Time.now - start) / 5
167
- duration = run_and_report_duration do
168
- @hosts.each_with_index do |h, i|
169
- booting_host(h, try, attempts)
170
- end
171
- end
172
- @logger.notify "Spent %.2f seconds booting and waiting for vSphere registration" % duration
173
-
174
- try = (Time.now - start) / 5
175
- duration = run_and_report_duration do
176
- @hosts.each do |host|
177
- repeat_fibonacci_style_for 8 do
178
- @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress != nil
179
- end
180
- host[:ip] = @vsphere_helper.find_vms(host['vmhostname'])[host['vmhostname']].summary.guest.ipAddress
181
- enable_root(host)
182
- end
183
- end
184
-
185
- @logger.notify "Spent %.2f seconds waiting for DNS resolution" % duration
186
-
187
- rescue => e
188
- @vsphere_helper.close
189
- report_and_raise(@logger, e, "Vcloud.provision")
190
- end
191
-
192
- end
193
-
194
- def cleanup
195
- @logger.notify "Destroying vCloud boxes"
196
- connect_to_vsphere
197
-
198
- vm_names = @hosts.map {|h| h['vmhostname'] }.compact
199
- if @hosts.length != vm_names.length
200
- @logger.warn "Some hosts did not have vmhostname set correctly! This likely means VM provisioning was not successful"
201
- end
202
- vms = @vsphere_helper.find_vms vm_names
203
- begin
204
- vm_names.each do |name|
205
- unless vm = vms[name]
206
- @logger.warn "Unable to cleanup #{name}, couldn't find VM #{name} in vSphere!"
207
- next
208
- end
209
-
210
- if vm.runtime.powerState == 'poweredOn'
211
- @logger.notify "Shutting down #{vm.name}"
212
- duration = run_and_report_duration do
213
- vm.PowerOffVM_Task.wait_for_completion
214
- end
215
- @logger.notify "Spent %.2f seconds halting #{vm.name}" % duration
216
- end
217
-
218
- duration = run_and_report_duration do
219
- vm.Destroy_Task
220
- end
221
- @logger.notify "Spent %.2f seconds destroying #{vm.name}" % duration
222
-
223
- end
224
- rescue RbVmomi::Fault => ex
225
- if ex.fault.is_a?(RbVmomi::VIM::ManagedObjectNotFound)
226
- #it's already gone, don't bother trying to delete it
227
- name = vms.key(ex.fault.obj)
228
- vms.delete(name)
229
- vm_names.delete(name)
230
- @logger.warn "Unable to destroy #{name}, it was not found in vSphere"
231
- retry
232
- end
233
- end
234
- @vsphere_helper.close
235
- end
236
-
237
- end
238
- end
@@ -1,79 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Beaker
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|
13
- arg
14
- end
15
- stub_const( "JSON", json )
16
- allow( Socket ).to receive( :getaddrinfo ).and_return( true )
17
- end
18
-
19
- describe "#provision" do
20
-
21
- it 'instantiates vmpooler if pooling api is provided' do
22
- opts = make_opts
23
- opts[:pooling_api] = 'testpool'
24
- hypervisor = Beaker::Vcloud.new( make_hosts, opts)
25
- expect( hypervisor.class ).to be Beaker::Vmpooler
26
- end
27
-
28
- it 'provisions hosts and add them to the pool' do
29
- MockVsphereHelper.powerOff
30
-
31
- opts = make_opts
32
- opts[:pooling_api] = nil
33
- opts[:datacenter] = 'testdc'
34
-
35
- vcloud = Beaker::Vcloud.new( make_hosts, opts )
36
- allow( vcloud ).to receive( :require ).and_return( true )
37
- allow( vcloud ).to receive( :sleep ).and_return( true )
38
- vcloud.provision
39
-
40
- hosts = vcloud.instance_variable_get( :@hosts )
41
- hosts.each do | host |
42
- name = host['vmhostname']
43
- vm = MockVsphereHelper.find_vm( name )
44
- expect( vm.toolsRunningStatus ).to be === "guestToolsRunning"
45
- end
46
-
47
- end
48
-
49
- end
50
-
51
- describe "#cleanup" do
52
-
53
- it "cleans up hosts not in the pool" do
54
- MockVsphereHelper.powerOn
55
-
56
- opts = make_opts
57
- opts[:pooling_api] = nil
58
- opts[:datacenter] = 'testdc'
59
-
60
- vcloud = Beaker::Vcloud.new( make_hosts, opts )
61
- allow( vcloud ).to receive( :require ).and_return( true )
62
- allow( vcloud ).to receive( :sleep ).and_return( true )
63
- vcloud.provision
64
- vcloud.cleanup
65
-
66
- hosts = vcloud.instance_variable_get( :@hosts )
67
- vm_names = hosts.map {|h| h['vmhostname'] }.compact
68
- vm_names.each do | name |
69
- vm = MockVsphereHelper.find_vm( name )
70
- expect( vm.runtime.powerState ).to be === "poweredOff"
71
- end
72
-
73
- end
74
-
75
- end
76
-
77
- end
78
-
79
- end