beaker-vcloud 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 :test => 'test:spec'
31
- task :default => :test
32
-
33
- ###########################################################
34
- #
35
- # Documentation Tasks
36
- #
37
- ###########################################################
38
- DOCS_DAEMON = "yard server --reload --daemon --server thin"
39
- FOREGROUND_SERVER = 'bundle exec yard server --reload --verbose --server thin lib/beaker'
40
-
41
- def running?( cmdline )
42
- ps = `ps -ef`
43
- found = ps.lines.grep( /#{Regexp.quote( cmdline )}/ )
44
- if found.length > 1
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
- namespace :docs do
65
-
66
- desc 'Clear the generated documentation cache'
67
- task :clear do
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
@@ -1,44 +1,32 @@
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-vcloud/version'
4
3
 
5
4
  Gem::Specification.new do |s|
6
- s.name = "beaker-vcloud"
5
+ s.name = 'beaker-vcloud'
7
6
  s.version = BeakerVcloud::VERSION
8
- s.authors = ["Rishi Javia, Kevin Imber, Tony Vu"]
9
- s.email = ["rishi.javia@puppet.com, kevin.imber@puppet.com, tony.vu@puppet.com"]
10
- s.homepage = "https://github.com/puppetlabs/beaker-vcloud"
11
- s.summary = %q{Beaker DSL Extension Helpers!}
12
- s.description = %q{For use for the Beaker acceptance testing tool}
13
- s.license = 'Apache2'
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.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 = '>= 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
- # pin fakefs for Ruby < 2.3
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,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.0.0'
2
+ VERSION = '2.0.0'
3
3
  end