beaker-vcloud 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.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/release.yml +32 -0
- data/.github/workflows/test.yml +58 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +292 -0
- data/CHANGELOG.md +79 -0
- data/Gemfile +7 -19
- data/README.md +28 -2
- data/Rakefile +20 -116
- data/beaker-vcloud.gemspec +19 -31
- data/bin/beaker-vcloud +1 -3
- data/lib/beaker/hypervisor/vcloud.rb +79 -88
- data/lib/beaker-vcloud/version.rb +1 -1
- data/spec/beaker/hypervisor/vcloud_spec.rb +39 -49
- data/spec/mock_vsphere.rb +284 -0
- data/spec/mock_vsphere_helper.rb +167 -0
- data/spec/spec_helper.rb +28 -3
- metadata +58 -81
data/Rakefile
CHANGED
@@ -1,24 +1,13 @@
|
|
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
|
-
|
13
|
-
desc "Run spec tests with coverage"
|
14
|
-
RSpec::Core::RakeTask.new(:coverage) do |t|
|
15
|
-
ENV['BEAKER_VCLOUD_COVERAGE'] = 'y'
|
16
|
-
t.rspec_opts = ['--color']
|
17
|
-
t.pattern = 'spec/'
|
18
|
-
end
|
19
|
-
|
20
10
|
end
|
21
|
-
|
22
11
|
end
|
23
12
|
|
24
13
|
# namespace-named default tasks.
|
@@ -27,111 +16,26 @@ end
|
|
27
16
|
task 'test:spec' => 'test:spec:run'
|
28
17
|
|
29
18
|
# global defaults
|
30
|
-
task :
|
31
|
-
task :
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
raise StandardError, "Found multiple YARD Servers. Don't know what to do."
|
19
|
+
task test: 'test:spec'
|
20
|
+
task default: :test
|
21
|
+
|
22
|
+
begin
|
23
|
+
require 'rubygems'
|
24
|
+
require 'github_changelog_generator/task'
|
25
|
+
rescue LoadError
|
26
|
+
# github_changelog_generator is an optional group
|
27
|
+
else
|
28
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
29
|
+
config.exclude_labels = %w[duplicate question invalid wontfix wont-fix skip-changelog github_actions]
|
30
|
+
config.user = 'voxpupuli'
|
31
|
+
config.project = 'beaker-vcloud'
|
32
|
+
gem_version = Gem::Specification.load("#{config.project}.gemspec").version
|
33
|
+
config.future_release = gem_version
|
46
34
|
end
|
47
|
-
|
48
|
-
yes = found.empty? ? false : true
|
49
|
-
return yes, found.first
|
50
|
-
end
|
51
|
-
|
52
|
-
def pid_from( output )
|
53
|
-
output.squeeze(' ').strip.split(' ')[1]
|
54
|
-
end
|
55
|
-
|
56
|
-
desc 'Start the documentation server in the foreground'
|
57
|
-
task :docs => 'docs:clear' do
|
58
|
-
original_dir = Dir.pwd
|
59
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
60
|
-
sh FOREGROUND_SERVER
|
61
|
-
Dir.chdir( original_dir )
|
62
35
|
end
|
63
36
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
original_dir = Dir.pwd
|
69
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
70
|
-
sh 'rm -rf docs'
|
71
|
-
Dir.chdir( original_dir )
|
72
|
-
end
|
73
|
-
|
74
|
-
desc 'Generate static documentation'
|
75
|
-
task :gen => 'docs:clear' do
|
76
|
-
original_dir = Dir.pwd
|
77
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
78
|
-
output = `bundle exec yard doc`
|
79
|
-
puts output
|
80
|
-
if output =~ /\[warn\]|\[error\]/
|
81
|
-
fail "Errors/Warnings during yard documentation generation"
|
82
|
-
end
|
83
|
-
Dir.chdir( original_dir )
|
84
|
-
end
|
85
|
-
|
86
|
-
desc 'Run the documentation server in the background, alias `bg`'
|
87
|
-
task :background => 'docs:clear' do
|
88
|
-
yes, output = running?( DOCS_DAEMON )
|
89
|
-
if yes
|
90
|
-
puts "Not starting a new YARD Server..."
|
91
|
-
puts "Found one running with pid #{pid_from( output )}."
|
92
|
-
else
|
93
|
-
original_dir = Dir.pwd
|
94
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
95
|
-
sh "bundle exec #{DOCS_DAEMON}"
|
96
|
-
Dir.chdir( original_dir )
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
task(:bg) { Rake::Task['docs:background'].invoke }
|
101
|
-
|
102
|
-
desc 'Check the status of the documentation server'
|
103
|
-
task :status do
|
104
|
-
yes, output = running?( DOCS_DAEMON )
|
105
|
-
if yes
|
106
|
-
pid = pid_from( output )
|
107
|
-
puts "Found a YARD Server running with pid #{pid}"
|
108
|
-
else
|
109
|
-
puts "Could not find a running YARD Server."
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
desc "Stop a running YARD Server"
|
114
|
-
task :stop do
|
115
|
-
yes, output = running?( DOCS_DAEMON )
|
116
|
-
if yes
|
117
|
-
pid = pid_from( output )
|
118
|
-
puts "Found a YARD Server running with pid #{pid}"
|
119
|
-
`kill #{pid}`
|
120
|
-
puts "Stopping..."
|
121
|
-
yes, output = running?( DOCS_DAEMON )
|
122
|
-
if yes
|
123
|
-
`kill -9 #{pid}`
|
124
|
-
yes, output = running?( DOCS_DAEMON )
|
125
|
-
if yes
|
126
|
-
puts "Could not Stop Server!"
|
127
|
-
else
|
128
|
-
puts "Server stopped."
|
129
|
-
end
|
130
|
-
else
|
131
|
-
puts "Server stopped."
|
132
|
-
end
|
133
|
-
else
|
134
|
-
puts "Could not find a running YARD Server"
|
135
|
-
end
|
136
|
-
end
|
37
|
+
begin
|
38
|
+
require 'voxpupuli/rubocop/rake'
|
39
|
+
rescue LoadError
|
40
|
+
# the voxpupuli-rubocop gem is optional
|
137
41
|
end
|
data/beaker-vcloud.gemspec
CHANGED
@@ -1,44 +1,32 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
1
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
3
2
|
require 'beaker-vcloud/version'
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
5
|
+
s.name = 'beaker-vcloud'
|
7
6
|
s.version = BeakerVcloud::VERSION
|
8
|
-
s.authors = [
|
9
|
-
s.email = [
|
10
|
-
s.homepage =
|
11
|
-
s.summary =
|
12
|
-
s.description =
|
13
|
-
s.license = '
|
7
|
+
s.authors = ['Vox Pupuli']
|
8
|
+
s.email = ['voxpupuli@groups.io']
|
9
|
+
s.homepage = 'https://github.com/voxpupuli/beaker-vcloud'
|
10
|
+
s.summary = 'Beaker DSL Extension Helpers!'
|
11
|
+
s.description = 'For use for the Beaker acceptance testing tool'
|
12
|
+
s.license = 'Apache-2.0'
|
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 = '>= 2.7'
|
19
19
|
|
20
20
|
# Testing dependencies
|
21
|
+
s.add_development_dependency 'fakefs', '~> 2.5'
|
22
|
+
s.add_development_dependency 'rake', '~> 13.2', '>= 13.2.1'
|
21
23
|
s.add_development_dependency 'rspec', '~> 3.0'
|
22
|
-
s.add_development_dependency 'rspec-its'
|
23
|
-
|
24
|
-
if RUBY_VERSION < "2.3"
|
25
|
-
s.add_development_dependency 'fakefs', '~> 0.6', '< 0.14'
|
26
|
-
else
|
27
|
-
s.add_development_dependency 'fakefs', '~> 0.6'
|
28
|
-
end
|
29
|
-
s.add_development_dependency 'rake', '~> 10.1'
|
30
|
-
s.add_development_dependency 'simplecov'
|
31
|
-
s.add_development_dependency 'pry', '~> 0.10'
|
32
|
-
|
33
|
-
# Documentation dependencies
|
34
|
-
s.add_development_dependency 'yard'
|
35
|
-
s.add_development_dependency 'markdown'
|
36
|
-
s.add_development_dependency 'thin'
|
24
|
+
s.add_development_dependency 'rspec-its', '~> 1.3'
|
25
|
+
s.add_development_dependency 'voxpupuli-rubocop', '~> 2.6.0'
|
37
26
|
|
38
27
|
# Run time dependencies
|
28
|
+
s.add_runtime_dependency 'beaker', '~> 5.8'
|
29
|
+
s.add_runtime_dependency 'beaker-vmware', '~> 2.1'
|
30
|
+
s.add_runtime_dependency 'rbvmomi2', '~> 3.7', '>= 3.7.1'
|
39
31
|
s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
|
40
|
-
s.add_runtime_dependency 'rbvmomi', '~> 1.9'
|
41
|
-
s.add_runtime_dependency 'beaker-vmware'
|
42
|
-
|
43
32
|
end
|
44
|
-
|
data/bin/beaker-vcloud
CHANGED
@@ -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
|
12
|
-
|
13
|
-
|
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
|
-
|
31
|
+
" with credentials for #{@vcenter_credentials[:vsphere_username]}"
|
32
32
|
|
33
|
-
@vsphere_helper = VsphereHelper.new :
|
34
|
-
:
|
35
|
-
:
|
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
|
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
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
sleep 5
|
46
|
+
try += 1
|
47
|
+
|
48
|
+
retry
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
54
|
-
def booting_host
|
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
|
-
|
58
|
-
@
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
74
|
+
def create_clone_spec(host)
|
79
75
|
# Add VM annotation
|
80
76
|
configSpec = RbVmomi::VIM.VirtualMachineConfigSpec(
|
81
|
-
:
|
82
|
-
'
|
83
|
-
'
|
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
|
-
:
|
88
|
-
{ :
|
89
|
-
:
|
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(
|
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
|
-
:
|
105
|
-
:
|
106
|
-
|
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
|
-
|
111
|
-
:
|
112
|
-
:
|
113
|
-
:
|
114
|
-
:
|
115
|
-
:
|
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,
|
130
|
-
|
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
|
137
|
-
h['template'] = ENV
|
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
|
-
|
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']] =
|
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(
|
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'
|
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,
|
168
|
+
@hosts.each_with_index do |h, _i|
|
174
169
|
booting_host(h, try, attempts)
|
175
170
|
end
|
176
171
|
end
|
177
|
-
@logger.notify
|
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
|
-
|
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
|
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,
|
188
|
+
report_and_raise(@logger, e, 'Vcloud.provision')
|
195
189
|
end
|
196
|
-
|
197
190
|
end
|
198
191
|
|
199
192
|
def cleanup
|
200
|
-
@logger.notify
|
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
|
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 =>
|
230
|
-
if
|
231
|
-
#it's already gone, don't bother trying to delete it
|
232
|
-
name = vms.key(
|
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
|