vmpooler 0.10.3 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,27 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  module Vmpooler
4
6
  class Providers
5
-
6
7
  # @param names [Array] - an array of names or string name of a provider
7
8
  # @return [Array] - list of provider files loaded
8
9
  # ie. ["lib/vmpooler/providers/base.rb", "lib/vmpooler/providers/dummy.rb", "lib/vmpooler/providers/vsphere.rb"]
9
10
  def self.load_by_name(names)
10
11
  names = Array(names)
11
- instance = self.new
12
- names.map {|name| instance.load_from_gems(name)}.flatten
12
+ instance = new
13
+ names.map { |name| instance.load_from_gems(name) }.flatten
13
14
  end
14
15
 
15
16
  # @return [Array] - array of provider files
16
17
  # ie. ["lib/vmpooler/providers/base.rb", "lib/vmpooler/providers/dummy.rb", "lib/vmpooler/providers/vsphere.rb"]
17
18
  # although these files can come from any gem
18
19
  def self.load_all_providers
19
- self.new.load_from_gems
20
+ new.load_from_gems
20
21
  end
21
22
 
22
23
  # @return [Array] - returns an array of gem names that contain a provider
23
24
  def self.installed_providers
24
- self.new.vmpooler_provider_gem_list.map(&:name)
25
+ new.vmpooler_provider_gem_list.map(&:name)
25
26
  end
26
27
 
27
28
  # @return [Array] returns a list of vmpooler providers gem plugin specs
@@ -38,7 +39,7 @@ module Vmpooler
38
39
  # we don't exactly know if the provider name matches the main file name that should be loaded
39
40
  # so we use globs to get everything like the name
40
41
  # this could mean that vsphere5 and vsphere6 are loaded when only vsphere5 is used
41
- Dir.glob(File.join(gem_path, "*#{name}*.rb")).each do |file|
42
+ Dir.glob(File.join(gem_path, "*#{name}*.rb")).sort.each do |file|
42
43
  require file
43
44
  end
44
45
  end
@@ -50,7 +51,7 @@ module Vmpooler
50
51
  # @return [String] - the relative path to the vmpooler provider dir
51
52
  # this is used when searching gems for this path
52
53
  def provider_path
53
- File.join('lib','vmpooler','providers')
54
+ File.join('lib', 'vmpooler', 'providers')
54
55
  end
55
56
 
56
57
  # Add constants to array to skip over classes, ie. Vmpooler::PoolManager::Provider::Dummy
@@ -81,26 +82,24 @@ module Vmpooler
81
82
  @plugin_map ||= Hash[plugin_classes.map { |gem| [gem.send(:name), gem] }]
82
83
  end
83
84
 
84
-
85
-
86
85
  # Internal: Retrieve a list of available gem paths from RubyGems.
87
86
  #
88
87
  # Returns an Array of Pathname objects.
89
88
  def gem_directories
90
89
  dirs = []
91
- if has_rubygems?
90
+ if rubygems?
92
91
  dirs = gemspecs.map do |spec|
93
- lib_path = File.expand_path(File.join(spec.full_gem_path,provider_path))
94
- lib_path if File.exists? lib_path
92
+ lib_path = File.expand_path(File.join(spec.full_gem_path, provider_path))
93
+ lib_path if File.exist? lib_path
95
94
  end + included_lib_dirs
96
95
  end
97
- dirs.reject { |dir| dir.nil? }.uniq
96
+ dirs.reject(&:nil?).uniq
98
97
  end
99
98
 
100
99
  # Internal: Check if RubyGems is loaded and available.
101
100
  #
102
101
  # Returns true if RubyGems is available, false if not.
103
- def has_rubygems?
102
+ def rubygems?
104
103
  defined? ::Gem
105
104
  end
106
105
 
@@ -114,6 +113,5 @@ module Vmpooler
114
113
  Gem.searcher.init_gemspecs
115
114
  end
116
115
  end
117
-
118
116
  end
119
117
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vmpooler
2
4
  class PoolManager
3
5
  class Provider
@@ -222,7 +224,7 @@ module Vmpooler
222
224
  # [Hash] pool : Configuration for the pool
223
225
  # returns
224
226
  # nil when successful. Raises error when encountered
225
- def create_template_delta_disks(pool)
227
+ def create_template_delta_disks(_pool)
226
228
  raise("#{self.class.name} does not implement create_template_delta_disks")
227
229
  end
228
230
 
@@ -230,11 +232,11 @@ module Vmpooler
230
232
  # [String] provider_name : Name of the provider
231
233
  # returns
232
234
  # Hash of folders
233
- def get_target_datacenter_from_config(provider_name)
235
+ def get_target_datacenter_from_config(_provider_name)
234
236
  raise("#{self.class.name} does not implement get_target_datacenter_from_config")
235
237
  end
236
238
 
237
- def purge_unconfigured_folders(base_folders, configured_folders, whitelist)
239
+ def purge_unconfigured_folders(_base_folders, _configured_folders, _whitelist)
238
240
  raise("#{self.class.name} does not implement purge_unconfigured_folders")
239
241
  end
240
242
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
  require 'vmpooler/providers/base'
3
5
 
@@ -73,10 +75,10 @@ module Vmpooler
73
75
  return current_vm['vm_host'] if provider_config['migratevm_couldmove_percent'].nil?
74
76
 
75
77
  # Only migrate if migratevm_couldmove_percent is met
76
- return current_vm['vm_host'] if 1 + rand(100) > provider_config['migratevm_couldmove_percent']
78
+ return current_vm['vm_host'] if rand(1..100) > provider_config['migratevm_couldmove_percent']
77
79
 
78
80
  # Simulate a 10 node cluster and randomly pick a different one
79
- new_host = 'HOST' + (1 + rand(10)).to_s while new_host == current_vm['vm_host']
81
+ new_host = 'HOST' + rand(1..10).to_s while new_host == current_vm['vm_host']
80
82
 
81
83
  new_host
82
84
  end
@@ -93,7 +95,7 @@ module Vmpooler
93
95
 
94
96
  # Inject clone failure
95
97
  unless provider_config['migratevm_fail_percent'].nil?
96
- raise('Dummy Failure for migratevm_fail_percent') if 1 + rand(100) <= provider_config['migratevm_fail_percent']
98
+ raise('Dummy Failure for migratevm_fail_percent') if rand(1..100) <= provider_config['migratevm_fail_percent']
97
99
  end
98
100
 
99
101
  @write_lock.synchronize do
@@ -114,7 +116,7 @@ module Vmpooler
114
116
 
115
117
  # Randomly power off the VM
116
118
  unless dummy['powerstate'] != 'PoweredOn' || provider_config['getvm_poweroff_percent'].nil?
117
- if 1 + rand(100) <= provider_config['getvm_poweroff_percent']
119
+ if rand(1..100) <= provider_config['getvm_poweroff_percent']
118
120
  @write_lock.synchronize do
119
121
  dummy = get_dummy_vm(pool_name, vm_name)
120
122
  dummy['powerstate'] = 'PoweredOff'
@@ -126,7 +128,7 @@ module Vmpooler
126
128
 
127
129
  # Randomly rename the host
128
130
  unless dummy['hostname'] != dummy['name'] || provider_config['getvm_rename_percent'].nil?
129
- if 1 + rand(100) <= provider_config['getvm_rename_percent']
131
+ if rand(1..100) <= provider_config['getvm_rename_percent']
130
132
  @write_lock.synchronize do
131
133
  dummy = get_dummy_vm(pool_name, vm_name)
132
134
  dummy['hostname'] = 'DUMMY' + dummy['name']
@@ -194,7 +196,7 @@ module Vmpooler
194
196
  begin
195
197
  # Inject clone failure
196
198
  unless provider_config['createvm_fail_percent'].nil?
197
- raise('Dummy Failure for createvm_fail_percent') if 1 + rand(100) <= provider_config['createvm_fail_percent']
199
+ raise('Dummy Failure for createvm_fail_percent') if rand(1..100) <= provider_config['createvm_fail_percent']
198
200
  end
199
201
 
200
202
  # Assert the VM is ready for use
@@ -202,7 +204,7 @@ module Vmpooler
202
204
  vm['dummy_state'] = 'RUNNING'
203
205
  write_backing_file
204
206
  end
205
- rescue => _err
207
+ rescue StandardError => _e
206
208
  @write_lock.synchronize do
207
209
  remove_dummy_vm(pool_name, dummy_hostname)
208
210
  write_backing_file
@@ -227,7 +229,7 @@ module Vmpooler
227
229
 
228
230
  # Inject create failure
229
231
  unless provider_config['createdisk_fail_percent'].nil?
230
- raise('Dummy Failure for createdisk_fail_percent') if 1 + rand(100) <= provider_config['createdisk_fail_percent']
232
+ raise('Dummy Failure for createdisk_fail_percent') if rand(1..100) <= provider_config['createdisk_fail_percent']
231
233
  end
232
234
 
233
235
  @write_lock.synchronize do
@@ -253,7 +255,7 @@ module Vmpooler
253
255
 
254
256
  # Inject create failure
255
257
  unless provider_config['createsnapshot_fail_percent'].nil?
256
- raise('Dummy Failure for createsnapshot_fail_percent') if 1 + rand(100) <= provider_config['createsnapshot_fail_percent']
258
+ raise('Dummy Failure for createsnapshot_fail_percent') if rand(1..100) <= provider_config['createsnapshot_fail_percent']
257
259
  end
258
260
 
259
261
  @write_lock.synchronize do
@@ -280,7 +282,7 @@ module Vmpooler
280
282
 
281
283
  # Inject create failure
282
284
  unless provider_config['revertsnapshot_fail_percent'].nil?
283
- raise('Dummy Failure for revertsnapshot_fail_percent') if 1 + rand(100) <= provider_config['revertsnapshot_fail_percent']
285
+ raise('Dummy Failure for revertsnapshot_fail_percent') if rand(1..100) <= provider_config['revertsnapshot_fail_percent']
284
286
  end
285
287
  end
286
288
 
@@ -318,7 +320,7 @@ module Vmpooler
318
320
 
319
321
  # Inject destroy VM failure
320
322
  unless provider_config['destroyvm_fail_percent'].nil?
321
- raise('Dummy Failure for migratevm_fail_percent') if 1 + rand(100) <= provider_config['destroyvm_fail_percent']
323
+ raise('Dummy Failure for migratevm_fail_percent') if rand(1..100) <= provider_config['destroyvm_fail_percent']
322
324
  end
323
325
 
324
326
  # 'Destroy' the VM
@@ -352,7 +354,7 @@ module Vmpooler
352
354
  sleep(2)
353
355
 
354
356
  unless provider_config['vmready_fail_percent'].nil?
355
- raise('Dummy Failure for vmready_fail_percent') if 1 + rand(100) <= provider_config['vmready_fail_percent']
357
+ raise('Dummy Failure for vmready_fail_percent') if rand(1..100) <= provider_config['vmready_fail_percent']
356
358
  end
357
359
 
358
360
  @write_lock.synchronize do
@@ -370,6 +372,7 @@ module Vmpooler
370
372
 
371
373
  def remove_dummy_vm(pool_name, vm_name)
372
374
  return if @dummylist['pool'][pool_name].nil?
375
+
373
376
  new_poollist = @dummylist['pool'][pool_name].delete_if { |vm| vm['name'] == vm_name }
374
377
  @dummylist['pool'][pool_name] = new_poollist
375
378
  end
@@ -395,6 +398,7 @@ module Vmpooler
395
398
  def write_backing_file
396
399
  dummyfilename = provider_config['filename']
397
400
  return if dummyfilename.nil?
401
+
398
402
  File.open(dummyfilename, 'w') { |file| file.write(YAML.dump(@dummylist)) }
399
403
  end
400
404
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'vmpooler/providers/base'
2
4
 
3
5
  module Vmpooler
@@ -50,7 +52,8 @@ module Vmpooler
50
52
  end
51
53
  return false unless configured_folders.keys.include?(folder_title)
52
54
  return false unless configured_folders[folder_title] == base_folder
53
- return true
55
+
56
+ true
54
57
  end
55
58
 
56
59
  def destroy_vm_and_log(vm_name, vm_object, pool, data_ttl)
@@ -69,17 +72,17 @@ module Vmpooler
69
72
  logger.log('s', "[!] [#{pool}] '#{vm_name}' is a folder, bailing on destroying")
70
73
  raise('Expected VM, but received a folder object')
71
74
  end
72
- vm_object.PowerOffVM_Task.wait_for_completion if vm_object.runtime && vm_object.runtime.powerState && vm_object.runtime.powerState == 'poweredOn'
75
+ vm_object.PowerOffVM_Task.wait_for_completion if vm_object.runtime&.powerState && vm_object.runtime.powerState == 'poweredOn'
73
76
  vm_object.Destroy_Task.wait_for_completion
74
77
 
75
- finish = format('%.2f', Time.now - start)
78
+ finish = format('%<time>.2f', time: Time.now - start)
76
79
  logger.log('s', "[-] [#{pool}] '#{vm_name}' destroyed in #{finish} seconds")
77
80
  metrics.timing("destroy.#{pool}", finish)
78
81
  rescue RuntimeError
79
82
  raise
80
- rescue => err
83
+ rescue StandardError => e
81
84
  try += 1
82
- logger.log('s', "[!] [#{pool}] failed to destroy '#{vm_name}' with an error: #{err}")
85
+ logger.log('s', "[!] [#{pool}] failed to destroy '#{vm_name}' with an error: #{e}")
83
86
  try >= max_tries ? raise : retry
84
87
  end
85
88
 
@@ -104,7 +107,7 @@ module Vmpooler
104
107
  max_tries = 3
105
108
  logger.log('s', "[-] [#{folder_object.name}] removing unconfigured folder")
106
109
  folder_object.Destroy_Task.wait_for_completion
107
- rescue
110
+ rescue StandardError
108
111
  try += 1
109
112
  try >= max_tries ? raise : retry
110
113
  end
@@ -115,13 +118,11 @@ module Vmpooler
115
118
 
116
119
  base_folders.each do |base_folder|
117
120
  folder_children = get_folder_children(base_folder, connection)
118
- unless folder_children.empty?
119
- folder_children.each do |folder_hash|
120
- folder_hash.each do |folder_title, folder_object|
121
- unless folder_configured?(folder_title, base_folder, configured_folders, whitelist)
122
- destroy_folder_and_children(folder_object)
123
- end
124
- end
121
+ next if folder_children.empty?
122
+
123
+ folder_children.each do |folder_hash|
124
+ folder_hash.each do |folder_title, folder_object|
125
+ destroy_folder_and_children(folder_object) unless folder_configured?(folder_title, base_folder, configured_folders, whitelist)
125
126
  end
126
127
  end
127
128
  end
@@ -131,16 +132,17 @@ module Vmpooler
131
132
  def get_folder_children(folder_name, connection)
132
133
  folders = []
133
134
 
134
- propSpecs = {
135
- :entity => self,
136
- :inventoryPath => folder_name
135
+ propSpecs = { # rubocop:disable Naming/VariableName
136
+ entity: self,
137
+ inventoryPath: folder_name
137
138
  }
138
- folder_object = connection.searchIndex.FindByInventoryPath(propSpecs)
139
+ folder_object = connection.searchIndex.FindByInventoryPath(propSpecs) # rubocop:disable Naming/VariableName
139
140
 
140
141
  return folders if folder_object.nil?
141
142
 
142
143
  folder_object.childEntity.each do |folder|
143
144
  next unless folder.is_a? RbVmomi::VIM::Folder
145
+
144
146
  folders << { folder.name => folder }
145
147
  end
146
148
 
@@ -171,9 +173,9 @@ module Vmpooler
171
173
  target[dc]['checking'] = true
172
174
  hosts_hash = find_least_used_hosts(cluster, datacenter, percentage)
173
175
  target[dc] = hosts_hash
174
- rescue => _err
176
+ rescue StandardError
175
177
  target[dc] = {}
176
- raise(_err)
178
+ raise
177
179
  ensure
178
180
  target[dc]['check_time_finished'] = Time.now
179
181
  end
@@ -188,36 +190,36 @@ module Vmpooler
188
190
  cluster = get_target_cluster_from_config(pool_name)
189
191
  raise("cluster for pool #{pool_name} cannot be identified") if cluster.nil?
190
192
  raise("datacenter for pool #{pool_name} cannot be identified") if datacenter.nil?
193
+
191
194
  dc = "#{datacenter}_#{cluster}"
192
195
  unless target.key?(dc)
193
196
  select_target_hosts(target, cluster, datacenter)
194
197
  return
195
198
  end
196
- if target[dc].key?('checking')
197
- wait_for_host_selection(dc, target, loop_delay, max_age)
198
- end
199
+ wait_for_host_selection(dc, target, loop_delay, max_age) if target[dc].key?('checking')
199
200
  if target[dc].key?('check_time_finished')
200
- if now - target[dc]['check_time_finished'] > max_age
201
- select_target_hosts(target, cluster, datacenter)
202
- end
201
+ select_target_hosts(target, cluster, datacenter) if now - target[dc]['check_time_finished'] > max_age
203
202
  end
204
203
  end
205
204
 
206
205
  def wait_for_host_selection(dc, target, maxloop = 0, loop_delay = 1, max_age = 60)
207
206
  loop_count = 1
208
- until target.key?(dc) and target[dc].key?('check_time_finished')
207
+ until target.key?(dc) && target[dc].key?('check_time_finished')
209
208
  sleep(loop_delay)
210
- unless maxloop.zero?
209
+ unless maxloop == 0
211
210
  break if loop_count >= maxloop
211
+
212
212
  loop_count += 1
213
213
  end
214
214
  end
215
215
  return unless target[dc].key?('check_time_finished')
216
+
216
217
  loop_count = 1
217
218
  while Time.now - target[dc]['check_time_finished'] > max_age
218
219
  sleep(loop_delay)
219
- unless maxloop.zero?
220
+ unless maxloop == 0
220
221
  break if loop_count >= maxloop
222
+
221
223
  loop_count += 1
222
224
  end
223
225
  end
@@ -228,28 +230,29 @@ module Vmpooler
228
230
  cluster = get_target_cluster_from_config(pool_name)
229
231
  raise("cluster for pool #{pool_name} cannot be identified") if cluster.nil?
230
232
  raise("datacenter for pool #{pool_name} cannot be identified") if datacenter.nil?
233
+
231
234
  dc = "#{datacenter}_#{cluster}"
232
235
  @provider_hosts_lock.synchronize do
233
236
  if architecture
234
237
  raise("there is no candidate in vcenter that meets all the required conditions, that the cluster has available hosts in a 'green' status, not in maintenance mode and not overloaded CPU and memory") unless target[dc].key?('architectures')
238
+
235
239
  host = target[dc]['architectures'][architecture].shift
236
240
  target[dc]['architectures'][architecture] << host
237
241
  if target[dc]['hosts'].include?(host)
238
242
  target[dc]['hosts'].delete(host)
239
243
  target[dc]['hosts'] << host
240
244
  end
241
- return host
242
245
  else
243
246
  raise("there is no candidate in vcenter that meets all the required conditions, that the cluster has available hosts in a 'green' status, not in maintenance mode and not overloaded CPU and memory") unless target[dc].key?('hosts')
247
+
244
248
  host = target[dc]['hosts'].shift
245
249
  target[dc]['hosts'] << host
246
250
  target[dc]['architectures'].each do |arch|
247
- if arch.include?(host)
248
- target[dc]['architectures'][arch] = arch.partition { |v| v != host }.flatten
249
- end
251
+ target[dc]['architectures'][arch] = arch.partition { |v| v != host }.flatten if arch.include?(host)
250
252
  end
251
- return host
252
253
  end
254
+
255
+ return host
253
256
  end
254
257
  end
255
258
 
@@ -258,11 +261,13 @@ module Vmpooler
258
261
  cluster = get_target_cluster_from_config(pool_name)
259
262
  raise("cluster for pool #{pool_name} cannot be identified") if cluster.nil?
260
263
  raise("datacenter for pool #{pool_name} cannot be identified") if datacenter.nil?
264
+
261
265
  dc = "#{datacenter}_#{cluster}"
262
266
  raise("there is no candidate in vcenter that meets all the required conditions, that the cluster has available hosts in a 'green' status, not in maintenance mode and not overloaded CPU and memory") unless target[dc].key?('hosts')
263
267
  return true if target[dc]['hosts'].include?(parent_host)
264
268
  return true if target[dc]['architectures'][architecture].include?(parent_host)
265
- return false
269
+
270
+ false
266
271
  end
267
272
 
268
273
  def get_vm(pool_name, vm_name)
@@ -280,6 +285,7 @@ module Vmpooler
280
285
  def create_vm(pool_name, new_vmname)
281
286
  pool = pool_config(pool_name)
282
287
  raise("Pool #{pool_name} does not exist for the provider #{name}") if pool.nil?
288
+
283
289
  vm_hash = nil
284
290
  @connection_pool.with_metrics do |pool_object|
285
291
  connection = ensured_vsphere_connection(pool_object)
@@ -322,7 +328,7 @@ module Vmpooler
322
328
  host_object = find_host_by_dnsname(connection, target_host)
323
329
  relocate_spec.host = host_object
324
330
  else
325
- # Choose a cluster/host to place the new VM on
331
+ # Choose a cluster/host to place the new VM on
326
332
  target_cluster_object = find_cluster(target_cluster_name, connection, target_datacenter_name)
327
333
  relocate_spec.pool = target_cluster_object.resourcePool
328
334
  end
@@ -337,14 +343,12 @@ module Vmpooler
337
343
 
338
344
  begin
339
345
  vm_target_folder = find_vm_folder(pool_name, connection)
340
- if vm_target_folder.nil? and @config[:config].key?('create_folders') and @config[:config]['create_folders'] == true
341
- vm_target_folder = create_folder(connection, target_folder_path, target_datacenter_name)
342
- end
343
- rescue => _err
344
- if @config[:config].key?('create_folders') and @config[:config]['create_folders'] == true
346
+ vm_target_folder = create_folder(connection, target_folder_path, target_datacenter_name) if vm_target_folder.nil? && @config[:config].key?('create_folders') && (@config[:config]['create_folders'] == true)
347
+ rescue StandardError
348
+ if @config[:config].key?('create_folders') && (@config[:config]['create_folders'] == true)
345
349
  vm_target_folder = create_folder(connection, target_folder_path, target_datacenter_name)
346
350
  else
347
- raise(_err)
351
+ raise
348
352
  end
349
353
  end
350
354
 
@@ -418,7 +422,7 @@ module Vmpooler
418
422
  return true if vm_object.nil?
419
423
 
420
424
  # Poweroff the VM if it's running
421
- vm_object.PowerOffVM_Task.wait_for_completion if vm_object.runtime && vm_object.runtime.powerState && vm_object.runtime.powerState == 'poweredOn'
425
+ vm_object.PowerOffVM_Task.wait_for_completion if vm_object.runtime&.powerState && vm_object.runtime.powerState == 'poweredOn'
422
426
 
423
427
  # Kill it with fire
424
428
  vm_object.Destroy_Task.wait_for_completion
@@ -429,7 +433,7 @@ module Vmpooler
429
433
  def vm_ready?(_pool_name, vm_name)
430
434
  begin
431
435
  open_socket(vm_name, global_config[:config]['domain'])
432
- rescue => _err
436
+ rescue StandardError => _e
433
437
  return false
434
438
  end
435
439
 
@@ -464,9 +468,9 @@ module Vmpooler
464
468
  pool_configuration = pool_config(pool_name)
465
469
  return nil if pool_configuration.nil?
466
470
 
467
- hostname = vm_object.summary.guest.hostName if vm_object.summary && vm_object.summary.guest && vm_object.summary.guest.hostName
468
- boottime = vm_object.runtime.bootTime if vm_object.runtime && vm_object.runtime.bootTime
469
- powerstate = vm_object.runtime.powerState if vm_object.runtime && vm_object.runtime.powerState
471
+ hostname = vm_object.summary.guest.hostName if vm_object.summary&.guest && vm_object.summary.guest.hostName
472
+ boottime = vm_object.runtime.bootTime if vm_object.runtime&.bootTime
473
+ powerstate = vm_object.runtime.powerState if vm_object.runtime&.powerState
470
474
 
471
475
  hash = {
472
476
  'name' => vm_object.name,
@@ -474,16 +478,16 @@ module Vmpooler
474
478
  'template' => pool_configuration['template'],
475
479
  'poolname' => pool_name,
476
480
  'boottime' => boottime,
477
- 'powerstate' => powerstate,
481
+ 'powerstate' => powerstate
478
482
  }
479
483
 
480
484
  hash
481
485
  end
482
486
 
483
487
  # vSphere helper methods
484
- ADAPTER_TYPE = 'lsiLogic'.freeze
485
- DISK_TYPE = 'thin'.freeze
486
- DISK_MODE = 'persistent'.freeze
488
+ ADAPTER_TYPE = 'lsiLogic'
489
+ DISK_TYPE = 'thin'
490
+ DISK_MODE = 'persistent'
487
491
 
488
492
  def ensured_vsphere_connection(connection_pool_object)
489
493
  connection_pool_object[:connection] = connect_to_vsphere unless vsphere_connection_ok?(connection_pool_object[:connection])
@@ -492,9 +496,9 @@ module Vmpooler
492
496
 
493
497
  def vsphere_connection_ok?(connection)
494
498
  _result = connection.serviceInstance.CurrentTime
495
- return true
496
- rescue
497
- return false
499
+ true
500
+ rescue StandardError
501
+ false
498
502
  end
499
503
 
500
504
  def connect_to_vsphere
@@ -507,10 +511,11 @@ module Vmpooler
507
511
  password: provider_config['password'],
508
512
  insecure: provider_config['insecure'] || false
509
513
  metrics.increment('connect.open')
510
- return connection
511
- rescue => err
514
+ connection
515
+ rescue StandardError => e
512
516
  metrics.increment('connect.fail')
513
- raise err if try >= max_tries
517
+ raise e if try >= max_tries
518
+
514
519
  sleep(try * retry_factor)
515
520
  try += 1
516
521
  retry
@@ -610,6 +615,7 @@ module Vmpooler
610
615
  def find_datastore(datastorename, connection, datacentername)
611
616
  datacenter = connection.serviceInstance.find_datacenter(datacentername)
612
617
  raise("Datacenter #{datacentername} does not exist") if datacenter.nil?
618
+
613
619
  datacenter.find_datastore(datastorename)
614
620
  end
615
621
 
@@ -625,9 +631,7 @@ module Vmpooler
625
631
  devices = find_disk_devices(vm)
626
632
 
627
633
  devices.keys.sort.each do |device|
628
- if devices[device]['children'].length < 15
629
- return find_device(vm, devices[device]['device'].deviceInfo.label)
630
- end
634
+ return find_device(vm, devices[device]['device'].deviceInfo.label) if devices[device]['children'].length < 15
631
635
  end
632
636
 
633
637
  nil
@@ -667,6 +671,7 @@ module Vmpooler
667
671
 
668
672
  devices.keys.sort.each do |c|
669
673
  next unless controller.key == devices[c]['device'].key
674
+
670
675
  used_unit_numbers.push(devices[c]['device'].scsiCtlrUnitNumber)
671
676
  devices[c]['children'].each do |disk|
672
677
  used_unit_numbers.push(disk.unitNumber)
@@ -674,12 +679,10 @@ module Vmpooler
674
679
  end
675
680
 
676
681
  (0..15).each do |scsi_id|
677
- if used_unit_numbers.grep(scsi_id).length <= 0
678
- available_unit_numbers.push(scsi_id)
679
- end
682
+ available_unit_numbers.push(scsi_id) if used_unit_numbers.grep(scsi_id).length <= 0
680
683
  end
681
684
 
682
- available_unit_numbers.sort[0]
685
+ available_unit_numbers.min
683
686
  end
684
687
 
685
688
  # Finds a folder object by inventory path
@@ -692,17 +695,19 @@ module Vmpooler
692
695
  # Returns nil when the object found is not a folder
693
696
  pool_configuration = pool_config(pool_name)
694
697
  return nil if pool_configuration.nil?
698
+
695
699
  folder = pool_configuration['folder']
696
700
  datacenter = get_target_datacenter_from_config(pool_name)
697
701
  return nil if datacenter.nil?
698
702
 
699
- propSpecs = {
700
- :entity => self,
701
- :inventoryPath => "#{datacenter}/vm/#{folder}"
703
+ propSpecs = { # rubocop:disable Naming/VariableName
704
+ entity: self,
705
+ inventoryPath: "#{datacenter}/vm/#{folder}"
702
706
  }
703
707
 
704
- folder_object = connection.searchIndex.FindByInventoryPath(propSpecs)
708
+ folder_object = connection.searchIndex.FindByInventoryPath(propSpecs) # rubocop:disable Naming/VariableName
705
709
  return nil unless folder_object.class == RbVmomi::VIM::Folder
710
+
706
711
  folder_object
707
712
  end
708
713
 
@@ -752,15 +757,17 @@ module Vmpooler
752
757
  def cpu_utilization_for(host)
753
758
  cpu_usage = host.summary.quickStats.overallCpuUsage
754
759
  return nil if cpu_usage.nil?
760
+
755
761
  cpu_size = host.summary.hardware.cpuMhz * host.summary.hardware.numCpuCores
756
- (cpu_usage.to_f / cpu_size.to_f) * 100
762
+ cpu_usage.fdiv(cpu_size) * 100
757
763
  end
758
764
 
759
765
  def memory_utilization_for(host)
760
766
  memory_usage = host.summary.quickStats.overallMemoryUsage
761
767
  return nil if memory_usage.nil?
768
+
762
769
  memory_size = host.summary.hardware.memorySize / 1024 / 1024
763
- (memory_usage.to_f / memory_size.to_f) * 100
770
+ memory_usage.fdiv(memory_size) * 100
764
771
  end
765
772
 
766
773
  def get_average_cluster_utilization(hosts)
@@ -769,13 +776,13 @@ module Vmpooler
769
776
  end
770
777
 
771
778
  def build_compatible_hosts_lists(hosts, percentage)
772
- hosts_with_arch_versions = hosts.map { |h|
779
+ hosts_with_arch_versions = hosts.map do |h|
773
780
  {
774
- 'utilization' => h[0],
775
- 'host_object' => h[1],
776
- 'architecture' => get_host_cpu_arch_version(h[1])
781
+ 'utilization' => h[0],
782
+ 'host_object' => h[1],
783
+ 'architecture' => get_host_cpu_arch_version(h[1])
777
784
  }
778
- }
785
+ end
779
786
  versions = hosts_with_arch_versions.map { |host| host['architecture'] }.uniq
780
787
  architectures = {}
781
788
  versions.each do |version|
@@ -787,7 +794,6 @@ module Vmpooler
787
794
  end
788
795
 
789
796
  versions.each do |version|
790
- targets = []
791
797
  targets = select_least_used_hosts(architectures[version], percentage)
792
798
  architectures[version] = targets
793
799
  end
@@ -796,12 +802,13 @@ module Vmpooler
796
802
 
797
803
  def select_least_used_hosts(hosts, percentage)
798
804
  raise('Provided hosts list to select_least_used_hosts is empty') if hosts.empty?
805
+
799
806
  average_utilization = get_average_cluster_utilization(hosts)
800
807
  least_used_hosts = []
801
808
  hosts.each do |host|
802
809
  least_used_hosts << host if host[0] <= average_utilization
803
810
  end
804
- hosts_to_select = (hosts.count * (percentage / 100.0)).to_int
811
+ hosts_to_select = (hosts.count * (percentage / 100.0)).to_int
805
812
  hosts_to_select = hosts.count - 1 if percentage == 100
806
813
  least_used_hosts.sort[0..hosts_to_select].map { |host| host[1].name }
807
814
  end
@@ -811,8 +818,10 @@ module Vmpooler
811
818
  connection = ensured_vsphere_connection(pool_object)
812
819
  cluster_object = find_cluster(cluster, connection, datacentername)
813
820
  raise("Cluster #{cluster} cannot be found") if cluster_object.nil?
821
+
814
822
  target_hosts = get_cluster_host_utilization(cluster_object)
815
823
  raise("there is no candidate in vcenter that meets all the required conditions, that the cluster has available hosts in a 'green' status, not in maintenance mode and not overloaded CPU and memory'") if target_hosts.empty?
824
+
816
825
  architectures = build_compatible_hosts_lists(target_hosts, percentage)
817
826
  least_used_hosts = select_least_used_hosts(target_hosts, percentage)
818
827
  {
@@ -825,6 +834,7 @@ module Vmpooler
825
834
  def find_host_by_dnsname(connection, dnsname)
826
835
  host_object = connection.searchIndex.FindByDnsName(dnsName: dnsname, vmSearch: false)
827
836
  return nil if host_object.nil?
837
+
828
838
  host_object
829
839
  end
830
840
 
@@ -832,7 +842,8 @@ module Vmpooler
832
842
  cluster_object = find_cluster(cluster, connection, datacentername)
833
843
  target_hosts = get_cluster_host_utilization(cluster_object)
834
844
  raise("There is no host candidate in vcenter that meets all the required conditions, check that the cluster has available hosts in a 'green' status, not in maintenance mode and not overloaded CPU and memory'") if target_hosts.empty?
835
- least_used_host = target_hosts.sort[0][1]
845
+
846
+ least_used_host = target_hosts.min[1]
836
847
  least_used_host
837
848
  end
838
849
 
@@ -848,7 +859,7 @@ module Vmpooler
848
859
  cv = connection.serviceContent.viewManager.CreateContainerView(
849
860
  container: datacenter.hostFolder,
850
861
  type: ['ComputeResource', 'ClusterComputeResource'],
851
- recursive: true,
862
+ recursive: true
852
863
  )
853
864
  cluster = cv.view.find { |cluster_object| cluster_object.name == cluster }
854
865
  cv.DestroyView
@@ -870,7 +881,8 @@ module Vmpooler
870
881
  cluster = source_host.parent
871
882
  target_hosts = get_cluster_host_utilization(cluster, model)
872
883
  raise("There is no host candidate in vcenter that meets all the required conditions, check that the cluster has available hosts in a 'green' status, not in maintenance mode and not overloaded CPU and memory'") if target_hosts.empty?
873
- target_host = target_hosts.sort[0][1]
884
+
885
+ target_host = target_hosts.min[1]
874
886
  [target_host, target_host.name]
875
887
  end
876
888
 
@@ -878,12 +890,12 @@ module Vmpooler
878
890
  get_snapshot_list(vm.snapshot.rootSnapshotList, snapshotname) if vm.snapshot
879
891
  end
880
892
 
881
- def build_propSpecs(datacenter, folder, vmname)
882
- propSpecs = {
893
+ def build_propSpecs(datacenter, folder, vmname) # rubocop:disable Naming/MethodName
894
+ propSpecs = { # rubocop:disable Naming/VariableName
883
895
  entity => self,
884
896
  :inventoryPath => "#{datacenter}/vm/#{folder}/#{vmname}"
885
897
  }
886
- propSpecs
898
+ propSpecs # rubocop:disable Naming/VariableName
887
899
  end
888
900
 
889
901
  def find_vm(pool_name, vmname, connection)
@@ -891,16 +903,17 @@ module Vmpooler
891
903
  # Returns nil when a VM, or pool configuration, cannot be found
892
904
  pool_configuration = pool_config(pool_name)
893
905
  return nil if pool_configuration.nil?
906
+
894
907
  folder = pool_configuration['folder']
895
908
  datacenter = get_target_datacenter_from_config(pool_name)
896
909
  return nil if datacenter.nil?
897
910
 
898
- propSpecs = {
899
- :entity => self,
900
- :inventoryPath => "#{datacenter}/vm/#{folder}/#{vmname}"
911
+ propSpecs = { # rubocop:disable Naming/VariableName
912
+ entity: self,
913
+ inventoryPath: "#{datacenter}/vm/#{folder}/#{vmname}"
901
914
  }
902
915
 
903
- connection.searchIndex.FindByInventoryPath(propSpecs)
916
+ connection.searchIndex.FindByInventoryPath(propSpecs) # rubocop:disable Naming/VariableName
904
917
  end
905
918
 
906
919
  def get_base_vm_container_from(connection)
@@ -929,8 +942,10 @@ module Vmpooler
929
942
  def get_vm_details(pool_name, vm_name, connection)
930
943
  vm_object = find_vm(pool_name, vm_name, connection)
931
944
  return nil if vm_object.nil?
932
- parent_host_object = vm_object.summary.runtime.host if vm_object.summary && vm_object.summary.runtime && vm_object.summary.runtime.host
945
+
946
+ parent_host_object = vm_object.summary.runtime.host if vm_object.summary&.runtime && vm_object.summary.runtime.host
933
947
  raise('Unable to determine which host the VM is running on') if parent_host_object.nil?
948
+
934
949
  parent_host = parent_host_object.name
935
950
  architecture = get_host_cpu_arch_version(parent_host_object)
936
951
  {
@@ -944,6 +959,7 @@ module Vmpooler
944
959
  migration_limit = config[:config]['migration_limit']
945
960
  return false unless migration_limit.is_a? Integer
946
961
  return true if migration_limit > 0
962
+
947
963
  false
948
964
  end
949
965
 
@@ -958,7 +974,7 @@ module Vmpooler
958
974
  if migration_enabled? @config
959
975
  if migration_count >= migration_limit
960
976
  logger.log('s', "[ ] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}. No migration will be evaluated since the migration_limit has been reached")
961
- return
977
+ break
962
978
  end
963
979
  run_select_hosts(pool_name, @provider_hosts)
964
980
  if vm_in_target?(pool_name, vm_hash['host_name'], vm_hash['architecture'], @provider_hosts)
@@ -969,9 +985,9 @@ module Vmpooler
969
985
  else
970
986
  logger.log('s', "[ ] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}")
971
987
  end
972
- rescue => _err
988
+ rescue StandardError
973
989
  logger.log('s', "[!] [#{pool_name}] '#{vm_name}' is running on #{vm_hash['host_name']}")
974
- raise _err
990
+ raise
975
991
  end
976
992
  end
977
993
  end
@@ -991,11 +1007,11 @@ module Vmpooler
991
1007
  def migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, dest_host_name)
992
1008
  start = Time.now
993
1009
  migrate_vm_host(vm_hash['object'], target_host_object)
994
- finish = format('%.2f', Time.now - start)
1010
+ finish = format('%<time>.2f', time: Time.now - start)
995
1011
  metrics.timing("migrate.#{pool_name}", finish)
996
1012
  metrics.increment("migrate_from.#{vm_hash['host_name']}")
997
1013
  metrics.increment("migrate_to.#{dest_host_name}")
998
- checkout_to_migration = format('%.2f', Time.now - Time.parse($redis.hget("vmpooler__vm__#{vm_name}", 'checkout')))
1014
+ checkout_to_migration = format('%<time>.2f', time: Time.now - Time.parse($redis.hget("vmpooler__vm__#{vm_name}", 'checkout')))
999
1015
  $redis.hset("vmpooler__vm__#{vm_name}", 'migration_time', finish)
1000
1016
  $redis.hset("vmpooler__vm__#{vm_name}", 'checkout_to_migration', checkout_to_migration)
1001
1017
  finish
@@ -1008,8 +1024,9 @@ module Vmpooler
1008
1024
 
1009
1025
  def create_folder(connection, new_folder, datacenter)
1010
1026
  dc = connection.serviceInstance.find_datacenter(datacenter)
1011
- folder_object = dc.vmFolder.traverse(new_folder, type=RbVmomi::VIM::Folder, create=true)
1027
+ folder_object = dc.vmFolder.traverse(new_folder, RbVmomi::VIM::Folder, true)
1012
1028
  raise("Cannot create folder #{new_folder}") if folder_object.nil?
1029
+
1013
1030
  folder_object
1014
1031
  end
1015
1032
 
@@ -1017,12 +1034,12 @@ module Vmpooler
1017
1034
  datacenter = get_target_datacenter_from_config(pool['name'])
1018
1035
  raise('cannot find datacenter') if datacenter.nil?
1019
1036
 
1020
- propSpecs = {
1021
- :entity => self,
1022
- :inventoryPath => "#{datacenter}/vm/#{pool['template']}"
1037
+ propSpecs = { # rubocop:disable Naming/VariableName
1038
+ entity: self,
1039
+ inventoryPath: "#{datacenter}/vm/#{pool['template']}"
1023
1040
  }
1024
1041
 
1025
- template_vm_object = connection.searchIndex.FindByInventoryPath(propSpecs)
1042
+ template_vm_object = connection.searchIndex.FindByInventoryPath(propSpecs) # rubocop:disable Naming/VariableName
1026
1043
  raise("Pool #{pool['name']} specifies a template VM of #{pool['template']} which does not exist for the provider #{name}") if template_vm_object.nil?
1027
1044
 
1028
1045
  template_vm_object
@@ -1041,12 +1058,14 @@ module Vmpooler
1041
1058
  return false unless template.include?('/')
1042
1059
  return false if template[0] == '/'
1043
1060
  return false if template[-1] == '/'
1044
- return true
1061
+
1062
+ true
1045
1063
  end
1046
1064
 
1047
1065
  def get_disk_backing(pool)
1048
1066
  return :moveChildMostDiskBacking if linked_clone?(pool)
1049
- return :moveAllDiskBackingsAndConsolidate
1067
+
1068
+ :moveAllDiskBackingsAndConsolidate
1050
1069
  end
1051
1070
 
1052
1071
  def linked_clone?(pool)