beaker-vmpooler 0.2.0 → 1.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.
- checksums.yaml +8 -8
- data/beaker-vmpooler.gemspec +0 -1
- data/lib/beaker-vmpooler/version.rb +1 -1
- data/spec/spec_helper.rb +1 -2
- metadata +2 -18
- data/lib/beaker/hypervisor/vcloud.rb +0 -238
- data/spec/beaker/hypervisor/vcloud_spec.rb +0 -79
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
M2U4YmFhNjE0OTE4MzZkN2RhNWEzYWZlNGUxYjVmNjhhMGE3NDBjMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTU2MjlmNjRmNzg5Zjk4YmYzZmZlZGMyZWZjMjk5YmYyMmVjYzhkNQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NmVjYWYxODI2NDIyYzc2YzE4ZWUzZGNlZmMyNmQyMTliYzZhZTU0MzFmYTkx
|
10
|
+
ZDNiMTVkMjFiZTQzZGQ5YjgyMGFjNDUwNjIzMzc0MWM0YWViYmExNTgwY2Mz
|
11
|
+
NWYzNTQ1NzQwMzU1Y2IxMDI0MWFiMTFlMzc1OTllYjFhMmRmNTU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OGM2ODE3YmM5OGQ2ZWRlMWI3YmIwODM2ZTEyODllNWRiODZhYzQ4NDIyYzZm
|
14
|
+
MzYwZTk0YWM4ZTJlY2VhOGI2NzI1MTZlZDczMWZhYjRlMTE4YzgzNjJkNTYz
|
15
|
+
ZjEwNGM5YjRkZTA4NDM1ODhkY2M3N2YzOTVhZjIzZDQ2MThjYmE=
|
data/beaker-vmpooler.gemspec
CHANGED
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.
|
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-
|
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
|