rbvmomi2 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -25
  3. data/exe/rbvmomish +50 -48
  4. data/lib/rbvmomi/basic_types.rb +318 -294
  5. data/lib/rbvmomi/connection.rb +221 -216
  6. data/lib/rbvmomi/deserialization.rb +201 -205
  7. data/lib/rbvmomi/fault.rb +10 -9
  8. data/lib/rbvmomi/optimist.rb +51 -50
  9. data/lib/rbvmomi/pbm.rb +52 -50
  10. data/lib/rbvmomi/sms/SmsStorageManager.rb +2 -1
  11. data/lib/rbvmomi/sms.rb +48 -46
  12. data/lib/rbvmomi/sso.rb +13 -18
  13. data/lib/rbvmomi/trivial_soap.rb +9 -8
  14. data/lib/rbvmomi/type_loader.rb +100 -101
  15. data/lib/rbvmomi/utils/admission_control.rb +90 -106
  16. data/lib/rbvmomi/utils/deploy.rb +77 -85
  17. data/lib/rbvmomi/utils/leases.rb +31 -33
  18. data/lib/rbvmomi/utils/perfdump.rb +177 -207
  19. data/lib/rbvmomi/version.rb +2 -1
  20. data/lib/rbvmomi/vim/ComputeResource.rb +17 -15
  21. data/lib/rbvmomi/vim/Datacenter.rb +1 -0
  22. data/lib/rbvmomi/vim/Datastore.rb +18 -15
  23. data/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb +7 -6
  24. data/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb +3 -2
  25. data/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb +7 -6
  26. data/lib/rbvmomi/vim/Folder.rb +37 -33
  27. data/lib/rbvmomi/vim/HostSystem.rb +139 -136
  28. data/lib/rbvmomi/vim/ManagedEntity.rb +15 -14
  29. data/lib/rbvmomi/vim/ManagedObject.rb +11 -10
  30. data/lib/rbvmomi/vim/ObjectContent.rb +3 -1
  31. data/lib/rbvmomi/vim/ObjectUpdate.rb +3 -1
  32. data/lib/rbvmomi/vim/OvfManager.rb +50 -57
  33. data/lib/rbvmomi/vim/PerfCounterInfo.rb +4 -3
  34. data/lib/rbvmomi/vim/PerformanceManager.rb +28 -31
  35. data/lib/rbvmomi/vim/PropertyCollector.rb +8 -7
  36. data/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb +22 -21
  37. data/lib/rbvmomi/vim/ResourcePool.rb +19 -18
  38. data/lib/rbvmomi/vim/ServiceInstance.rb +8 -7
  39. data/lib/rbvmomi/vim/Task.rb +6 -5
  40. data/lib/rbvmomi/vim/VirtualMachine.rb +8 -7
  41. data/lib/rbvmomi/vim.rb +112 -129
  42. data/lib/rbvmomi.rb +1 -0
  43. metadata +54 -10
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
3
  # SPDX-License-Identifier: MIT
3
4
 
@@ -7,7 +8,7 @@ require_relative '../../rbvmomi'
7
8
 
8
9
  # The cached ovf deployer is an optimization on top of regular OVF deployment
9
10
  # as it is offered by the VIM::OVFManager. Creating a VM becomes a multi-stage
10
- # process: First the OVF is uploaded and instead of directly using it, it is
11
+ # process: First the OVF is uploaded and instead of directly using it, it is
11
12
  # prepared for linked cloning and marked as a template. It can then be cloned
12
13
  # many times over, without the cost of repeated OVF deploys (network and storage
13
14
  # IO) and the cost of storing the same base VM several times (storage space).
@@ -15,21 +16,21 @@ require_relative '../../rbvmomi'
15
16
  # automatically detected and de-duplicated. One thread will win to create the
16
17
  # OVF template, while the other will wait for the winning thread to finish the
17
18
  # task. So even fully independent, distributed and unsynchronized clients using
18
- # this call with be auto-synchronized just by talking to the same vCenter
19
- # instance and using the name naming scheme for the templates.
19
+ # this call with be auto-synchronized just by talking to the same vCenter
20
+ # instance and using the name naming scheme for the templates.
20
21
  #
21
- # The caching concept above can be extended to multiple levels. Lets assume
22
+ # The caching concept above can be extended to multiple levels. Lets assume
22
23
  # many VMs will share the same base OS, but are running different builds of the
23
- # application running inside the VM. If it is expected that again many (but not
24
- # all) VMs will share the same build of the application, a tree structure of
24
+ # application running inside the VM. If it is expected that again many (but not
25
+ # all) VMs will share the same build of the application, a tree structure of
25
26
  # templates becomes useful. At the root of the tree is the template with just
26
27
  # the base OS. It is uploaded from an OVF if needed. Then, this base OS image
27
28
  # is cloned, a particular build is installed and the resulting VM is again marked
28
- # as a template. Users can then instantiate that particular build with very
29
+ # as a template. Users can then instantiate that particular build with very
29
30
  # little extra overhead. This class supports such multi level templates via the
30
31
  # :is_template parameter of linked_clone().
31
32
  class CachedOvfDeployer
32
- # Constructor. Gets the VIM connection and important VIM objects
33
+ # Constructor. Gets the VIM connection and important VIM objects
33
34
  # @param vim [VIM] VIM Connection
34
35
  # @param network [VIM::Network] Network to attach templates and VMs to
35
36
  # @param computer [VIM::ComputeResource] Host/Cluster to deploy templates/VMs to
@@ -47,40 +48,40 @@ class CachedOvfDeployer
47
48
  @datastore = datastore
48
49
  @logger = opts[:logger]
49
50
  end
50
-
51
+
51
52
  def log x
52
- if @logger
53
+ if @logger
53
54
  @logger.info x
54
55
  else
55
56
  puts "#{Time.now}: #{x}"
56
57
  end
57
58
  end
58
-
59
- # Internal helper method that executes the passed in block while disabling
59
+
60
+ # Internal helper method that executes the passed in block while disabling
60
61
  # the handling of SIGINT and SIGTERM signals. Restores their handlers after
61
- # the block is executed.
62
+ # the block is executed.
62
63
  # @param enabled [Boolean] If false, this function is a no-op
63
64
  def _run_without_interruptions enabled
64
65
  if enabled
65
- int_handler = Signal.trap("SIGINT", 'IGNORE')
66
- term_handler = Signal.trap("SIGTERM", 'IGNORE')
66
+ int_handler = Signal.trap('SIGINT', 'IGNORE')
67
+ term_handler = Signal.trap('SIGTERM', 'IGNORE')
67
68
  end
68
-
69
+
69
70
  yield
70
-
71
+
71
72
  if enabled
72
- Signal.trap("SIGINT", int_handler)
73
- Signal.trap("SIGTERM", term_handler)
73
+ Signal.trap('SIGINT', int_handler)
74
+ Signal.trap('SIGTERM', term_handler)
74
75
  end
75
76
  end
76
-
77
+
77
78
  # Uploads an OVF, prepares the resulting VM for linked cloning and then marks
78
- # it as a template. If another thread happens to race to do the same task,
79
- # the losing thread will not do the actual work, but instead wait for the
79
+ # it as a template. If another thread happens to race to do the same task,
80
+ # the losing thread will not do the actual work, but instead wait for the
80
81
  # winning thread to do the work by looking up the template VM and waiting for
81
82
  # it to be marked as a template. This way, the cost of uploading and keeping
82
83
  # the full size of the VM is only paid once.
83
- # @param ovf_url [String] URL to the OVF to be deployed. Currently only http
84
+ # @param ovf_url [String] URL to the OVF to be deployed. Currently only http
84
85
  # and https are supported.
85
86
  # @param template_name [String] Name of the template to be used. Should be the
86
87
  # same name for the same URL. A cluster specific post-fix will automatically
@@ -95,58 +96,52 @@ class CachedOvfDeployer
95
96
  # Optimization: If there happens to be a fully prepared template, then
96
97
  # there is no need to do the complicated OVF upload dance
97
98
  template = lookup_template template_name
98
- if template
99
- return template
100
- end
101
-
99
+ return template if template
100
+
102
101
  # The OVFManager expects us to know the names of the networks mentioned
103
- # in the OVF file so we can map them to VIM::Network objects. For
104
- # simplicity this function assumes we need to read the OVF file
102
+ # in the OVF file so we can map them to VIM::Network objects. For
103
+ # simplicity this function assumes we need to read the OVF file
105
104
  # ourselves to know the names, and we map all of them to the same
106
105
  # VIM::Network.
107
106
 
108
107
  # If we're handling a file:// URI we need to strip the scheme as open-uri
109
108
  # can't handle them.
110
- if URI(ovf_url).scheme == "file" && URI(ovf_url).host.nil?
111
- ovf_url = URI(ovf_url).path
112
- end
109
+ ovf_url = URI(ovf_url).path if URI(ovf_url).scheme == 'file' && URI(ovf_url).host.nil?
113
110
 
114
- ovf = open(ovf_url, 'r'){|io| Nokogiri::XML(io.read)}
111
+ ovf = open(ovf_url, 'r'){ |io| Nokogiri::XML(io.read) }
115
112
  ovf.remove_namespaces!
116
- networks = ovf.xpath('//NetworkSection/Network').map{|x| x['name']}
117
- network_mappings = Hash[networks.map{|x| [x, @network]}]
113
+ networks = ovf.xpath('//NetworkSection/Network').map{ |x| x['name'] }
114
+ network_mappings = Hash[networks.map{ |x| [x, @network] }]
118
115
 
119
- network_mappings_str = network_mappings.map{|k, v| "#{k} = #{v.name}"}
116
+ network_mappings_str = network_mappings.map{ |k, v| "#{k} = #{v.name}" }
120
117
  log "networks: #{network_mappings_str.join(', ')}"
121
118
 
122
119
  pc = @vim.serviceContent.propertyCollector
123
-
120
+
124
121
  # OVFs need to be uploaded to a specific host. DRS won't just pick one
125
122
  # for us, so we need to pick one wisely. The host needs to be connected,
126
123
  # not be in maintenance mode and must have the destination datastore
127
124
  # accessible.
128
125
  hosts = @computer.host
129
126
  hosts_props = pc.collectMultiple(
130
- hosts,
131
- 'datastore', 'runtime.connectionState',
127
+ hosts,
128
+ 'datastore', 'runtime.connectionState',
132
129
  'runtime.inMaintenanceMode', 'name'
133
130
  )
134
131
  host = hosts.shuffle.find do |x|
135
- host_props = hosts_props[x]
132
+ host_props = hosts_props[x]
136
133
  is_connected = host_props['runtime.connectionState'] == 'connected'
137
134
  is_ds_accessible = host_props['datastore'].member?(@datastore)
138
135
  is_connected && is_ds_accessible && !host_props['runtime.inMaintenanceMode']
139
136
  end
140
- if !host
141
- fail "No host in the cluster available to upload OVF to"
142
- end
143
-
137
+ raise 'No host in the cluster available to upload OVF to' if !host
138
+
144
139
  log "Uploading OVF to #{hosts_props[host]['name']}..."
145
140
  property_mappings = {}
146
141
 
147
- # To work around the VMFS 8-host limit (existed until ESX 5.0), as
148
- # well as just for organization purposes, we create one template per
149
- # cluster. This also provides us with additional isolation.
142
+ # To work around the VMFS 8-host limit (existed until ESX 5.0), as
143
+ # well as just for organization purposes, we create one template per
144
+ # cluster. This also provides us with additional isolation.
150
145
  vm_name = template_name+"-#{@computer.name}"
151
146
 
152
147
  vm = nil
@@ -156,8 +151,8 @@ class CachedOvfDeployer
156
151
  # This is desirable, as other threads depend on this thread finishing
157
152
  # its prepare job and thus interrupting it has impacts beyond this
158
153
  # single thread or process.
159
- _run_without_interruptions(opts[:run_without_interruptions]) do
160
- begin
154
+ _run_without_interruptions(opts[:run_without_interruptions]) do
155
+ begin
161
156
  vm = @vim.serviceContent.ovfManager.deployOVF(
162
157
  uri: ovf_url,
163
158
  vmName: vm_name,
@@ -170,11 +165,11 @@ class CachedOvfDeployer
170
165
  rescue RbVmomi::Fault => fault
171
166
  # If two threads execute this script at the same time to upload
172
167
  # the same template under the same name, one will win and the other
173
- # with be rejected by VC. We catch those cases here, and handle
168
+ # with be rejected by VC. We catch those cases here, and handle
174
169
  # them by waiting for the winning thread to finish preparing the
175
170
  # template, see below ...
176
171
  is_duplicate = fault.fault.is_a?(RbVmomi::VIM::DuplicateName)
177
- is_duplicate ||= (fault.fault.is_a?(RbVmomi::VIM::InvalidState) &&
172
+ is_duplicate ||= (fault.fault.is_a?(RbVmomi::VIM::InvalidState) &&
178
173
  !fault.fault.is_a?(RbVmomi::VIM::InvalidHostState))
179
174
  if is_duplicate
180
175
  wait_for_template = true
@@ -182,7 +177,7 @@ class CachedOvfDeployer
182
177
  raise fault
183
178
  end
184
179
  end
185
-
180
+
186
181
  # The winning thread succeeded in uploading the OVF. Now we need to
187
182
  # prepare it for (linked) cloning and mark it as a template to signal
188
183
  # we are done.
@@ -191,29 +186,29 @@ class CachedOvfDeployer
191
186
  config = opts[:config] || {}
192
187
  config = vm.update_spec_add_delta_disk_layer_on_all_disks(config)
193
188
  # XXX: Should we add a version that does retries?
194
- vm.ReconfigVM_Task(:spec => config).wait_for_completion
189
+ vm.ReconfigVM_Task(spec: config).wait_for_completion
195
190
  end
196
191
  vm.MarkAsTemplate
197
192
  end
198
193
  end
199
-
194
+
200
195
  # The losing thread now needs to wait for the winning thread to finish
201
196
  # uploading and preparing the template
202
197
  if wait_for_template
203
- log "Template already exists, waiting for it to be ready"
198
+ log 'Template already exists, waiting for it to be ready'
204
199
  vm = _wait_for_template_ready @template_folder, vm_name
205
- log "Template fully prepared and ready to be cloned"
200
+ log 'Template fully prepared and ready to be cloned'
206
201
  end
207
-
202
+
208
203
  vm
209
204
  end
210
-
205
+
211
206
  # Looks up a template by name in the configured template_path. Should be used
212
- # before uploading the VM via upload_ovf_as_template, although that is
207
+ # before uploading the VM via upload_ovf_as_template, although that is
213
208
  # not strictly required, but a lot more efficient.
214
- # @param template_name [String] Name of the template to be used. A cluster
209
+ # @param template_name [String] Name of the template to be used. A cluster
215
210
  # specific post-fix will automatically be added.
216
- # @return [VIM::VirtualMachine] The template as a VIM::VirtualMachine instance
211
+ # @return [VIM::VirtualMachine] The template as a VIM::VirtualMachine instance
217
212
  # or nil
218
213
  def lookup_template template_name
219
214
  template_path = "#{template_name}-#{@computer.name}"
@@ -221,19 +216,17 @@ class CachedOvfDeployer
221
216
  if template
222
217
  config = template.config
223
218
  is_template = config && config.template
224
- if !is_template
225
- template = nil
226
- end
219
+ template = nil if !is_template
227
220
  end
228
221
  template
229
222
  end
230
-
223
+
231
224
  # Creates a linked clone of a template prepared with upload_ovf_as_template.
232
225
  # The function waits for completion on the clone task. Optionally, in case
233
- # two level templates are being used, this function can wait for another
226
+ # two level templates are being used, this function can wait for another
234
227
  # thread to finish creating the second level template. See class comments
235
228
  # for the concept of multi level templates.
236
- # @param template_name [String] Name of the template to be used. A cluster
229
+ # @param template_name [String] Name of the template to be used. A cluster
237
230
  # specific post-fix will automatically be added.
238
231
  # @param vm_name [String] Name of the new VM that is being created via cloning.
239
232
  # @param config [Hash] VM Config delta to apply after the VM is cloned.
@@ -246,11 +239,11 @@ class CachedOvfDeployer
246
239
  def linked_clone template_vm, vm_name, config, opts = {}
247
240
  spec = {
248
241
  location: {
249
- pool: @rp,
242
+ pool: @rp,
250
243
  datastore: @datastore,
251
244
  diskMoveType: :moveChildMostDiskBacking,
252
- },
253
- powerOn: false,
245
+ },
246
+ powerOn: false,
254
247
  template: false,
255
248
  config: config,
256
249
  }
@@ -259,8 +252,8 @@ class CachedOvfDeployer
259
252
  template_name = "#{vm_name}-#{@computer.name}"
260
253
  begin
261
254
  vm = template_vm.CloneVM_Task(
262
- folder: @template_folder,
263
- name: template_name,
255
+ folder: @template_folder,
256
+ name: template_name,
264
257
  spec: spec
265
258
  ).wait_for_completion
266
259
  rescue RbVmomi::Fault => fault
@@ -270,26 +263,26 @@ class CachedOvfDeployer
270
263
  raise
271
264
  end
272
265
  end
273
-
266
+
274
267
  if wait_for_template
275
268
  puts "#{Time.now}: Template already exists, waiting for it to be ready"
276
269
  vm = _wait_for_template_ready @template_folder, template_name
277
270
  puts "#{Time.now}: Template ready"
278
- end
271
+ end
279
272
  else
280
273
  vm = template_vm.CloneVM_Task(
281
- folder: @vmfolder,
282
- name: vm_name,
274
+ folder: @vmfolder,
275
+ name: vm_name,
283
276
  spec: spec
284
277
  ).wait_for_completion
285
278
  end
286
279
  vm
287
280
  end
288
281
 
289
- # Internal helper method that waits for a template to be fully created. It
282
+ # Internal helper method that waits for a template to be fully created. It
290
283
  # polls until it finds the VM in the inventory, and once it is there, waits
291
284
  # for it to be fully created and marked as a template. This function will
292
- # block for forever if the template never gets created or marked as a
285
+ # block for forever if the template never gets created or marked as a
293
286
  # template.
294
287
  # @param vm_folder [VIM::Folder] Folder in which we expect the template to show up
295
288
  # @param vm_name [String] Name of the VM we are waiting for
@@ -299,20 +292,19 @@ class CachedOvfDeployer
299
292
  while !vm
300
293
  sleep 3
301
294
  # XXX: Optimize this
302
- vm = vm_folder.children.find{|x| x.name == vm_name}
295
+ vm = vm_folder.children.find{ |x| x.name == vm_name }
303
296
  end
304
- log "Template VM found"
297
+ log 'Template VM found'
305
298
  sleep 2
306
299
  while true
307
300
  runtime, template = vm.collect 'runtime', 'config.template'
308
- ready = runtime && runtime.host && runtime.powerState == "poweredOff"
301
+ ready = runtime && runtime.host && runtime.powerState == 'poweredOff'
309
302
  ready = ready && template
310
- if ready
311
- break
312
- end
303
+ break if ready
304
+
313
305
  sleep 5
314
306
  end
315
-
307
+
316
308
  vm
317
309
  end
318
310
  end
@@ -1,26 +1,27 @@
1
+ # frozen_string_literal: true
1
2
  # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
3
  # SPDX-License-Identifier: MIT
3
4
 
4
5
  require 'yaml'
5
6
 
6
7
  # A class to manage VM leases
7
- #
8
+ #
8
9
  # This class uses YAML encoded VM annotations (config.annotation) to manage a
9
10
  # lease system. It helps add such lease info onto new and existing VMs and to
10
11
  # find VMs that have expired leases or that are about to have expired leases.
11
- # The calling code can use those to generate emails with about-to-expire
12
+ # The calling code can use those to generate emails with about-to-expire
12
13
  # notifications, suspend, power off or destroy VMs that have exceeded their
13
- # lease, etc.
14
+ # lease, etc.
14
15
  class LeaseTool
15
16
  # Lists of VM properties the LeaseTool needs to do its job. Can be used to
16
17
  # construct larger property collector calls that retrieve more info than just
17
18
  # one subsystem needs.
18
19
  # @return [Array] List of property names
19
- def vms_props_list
20
+ def vms_props_list
20
21
  ['name', 'config.annotation']
21
22
  end
22
-
23
- # Fetch all VM properties that the LeaseTool needs on all VMs passed in.
23
+
24
+ # Fetch all VM properties that the LeaseTool needs on all VMs passed in.
24
25
  # @param vms [Array] List of VIM::VirtualMachine instances
25
26
  # @return [Hash] Hash of VMs as keys and their properties as values
26
27
  def get_vms_props vms
@@ -31,34 +32,32 @@ class LeaseTool
31
32
  end
32
33
  out
33
34
  end
34
-
35
- # Retrieve the current time as used by the lease tool.
35
+
36
+ # Retrieve the current time as used by the lease tool.
36
37
  # @return [Time] Current time as used by the lease tool
37
38
  def current_time
38
39
  # XXX: Should swith to time provided by VC
39
40
  Time.now
40
41
  end
41
-
42
+
42
43
  # Helper function that sets the lease info in a passed in VM config. If there
43
44
  # is no annotation, it is added. If there is an annotation, it is updated to
44
- # include the lease info. Note that if the annotation isn't YAML, it is
45
- # overwritten.
45
+ # include the lease info. Note that if the annotation isn't YAML, it is
46
+ # overwritten.
46
47
  # @param vmconfig [Hash] Virtual Machine config spec
47
48
  # @param lease_minutes [int] Time to lease expiration from now in minutes
48
49
  # @return [Hash] Updated Virtual Machine config spec
49
50
  def set_lease_in_vm_config vmconfig, lease_minutes
50
51
  annotation = vmconfig[:annotation]
51
- annotation ||= ""
52
+ annotation ||= ''
52
53
  note = YAML.load annotation
53
- if !note.is_a?(Hash)
54
- note = {}
55
- end
54
+ note = {} if !note.is_a?(Hash)
56
55
  lease = current_time + lease_minutes * 60
57
56
  note['lease'] = lease
58
57
  vmconfig[:annotation] = YAML.dump(note)
59
58
  vmconfig
60
59
  end
61
-
60
+
62
61
  # Issue ReconfigVM_Task on the VM to update the lease. User can pass in current
63
62
  # annotation, but if not, it is retrieved on demand. A task is returned, i.e.
64
63
  # function doesn't wait for completion.
@@ -67,17 +66,15 @@ class LeaseTool
67
66
  # @param annotation [String] 'config.annotation' property of the VM. Optional.
68
67
  # @return [VIM::Task] VM reconfiguration task
69
68
  def set_lease_on_vm_task vm, lease_minutes, annotation = nil
70
- if !annotation
71
- annotation = vm.collect 'config.annotation'
72
- end
73
- vmconfig = {:annotation => annotation}
69
+ annotation = vm.collect 'config.annotation' if !annotation
70
+ vmconfig = {annotation: annotation}
74
71
  vmconfig = set_lease_in_vm_config vmconfig, lease_minutes
75
72
  # XXX: It may be a good idea to cite the VM version here to avoid
76
73
  # concurrent writes to the annotation stepping on each others toes
77
- vm.ReconfigVM_Task(:spec => vmconfig)
74
+ vm.ReconfigVM_Task(spec: vmconfig)
78
75
  end
79
-
80
- # Issue ReconfigVM_Task to set the lease on all VMs that currently do not
76
+
77
+ # Issue ReconfigVM_Task to set the lease on all VMs that currently do not
81
78
  # have a lease. All VM reconfigurations are done in parallel and the function
82
79
  # waits for all of them to complete
83
80
  # @param vms [Array] List of VIM::VirtualMachine instances, may or may not have leases
@@ -86,9 +83,8 @@ class LeaseTool
86
83
  # @return [Array] List of previously leaseless VMs that now have a lease
87
84
  def set_lease_on_leaseless_vms vms, vmprops, opts = {}
88
85
  lease_minutes = opts[:lease_minutes]
89
- if !lease_minutes
90
- raise "Expected lease_minutes to be specified"
91
- end
86
+ raise 'Expected lease_minutes to be specified' if !lease_minutes
87
+
92
88
  vms = find_leaseless_vms vms, vmprops
93
89
  if vms.length > 0
94
90
  tasks = vms.map do |vm|
@@ -101,12 +97,12 @@ class LeaseTool
101
97
  end
102
98
  vms
103
99
  end
104
-
100
+
105
101
  # Filter the list of passed in Virtual Machines and find the ones that currently
106
102
  # do not have a lease.
107
103
  # @param vms [Array] List of VIM::VirtualMachine instances, may or may not have leases
108
104
  # @param vmprops [Hash] Hash of VIM::VirtualMachine instances to their properties
109
- # @return [Array] List of leaseless VMs
105
+ # @return [Array] List of leaseless VMs
110
106
  def find_leaseless_vms vms, vmprops
111
107
  vms.reject do |vm|
112
108
  props = vmprops[vm]
@@ -118,24 +114,26 @@ class LeaseTool
118
114
  end
119
115
  end
120
116
 
121
- # Filter the list of passed in Virtul Machines and find the one that are
122
- # expired. A time offset can be used to identify VMs that will expire at
123
- # a certain point in the future.
117
+ # Filter the list of passed in Virtul Machines and find the one that are
118
+ # expired. A time offset can be used to identify VMs that will expire at
119
+ # a certain point in the future.
124
120
  # If a VM doesn't have a lease, it is treated as never expiring.
125
121
  # @param vms [Array] List of VIM::VirtualMachine instances, may or may not have leases
126
122
  # @param vmprops [Hash] Hash of VIM::VirtualMachine instances to their properties
127
123
  # @option opts [int] :time_delta Time delta (seconds) to be added to current time
128
- # @return [Array] List of expired VMs
124
+ # @return [Array] List of expired VMs
129
125
  def filter_expired_vms vms, vmprops, opts = {}
130
126
  time_delta = opts[:time_delta] || 0
131
127
  time = current_time + time_delta
132
-
128
+
133
129
  out = vms.map do |vm|
134
130
  props = vmprops[vm]
135
131
  next unless annotation = props['config.annotation']
132
+
136
133
  note = YAML.load annotation
137
134
  next unless note.is_a?(Hash) && lease = note['lease']
138
135
  next unless time > lease
136
+
139
137
  time_to_expiration = ((lease - time) + time_delta)
140
138
  [vm, time_to_expiration]
141
139
  end.compact