rbvmomi 1.6.0 → 1.8.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.
- data/Rakefile +13 -13
- data/VERSION +1 -1
- data/devel/analyze-vim-declarations.rb +17 -4
- data/devel/merge-internal-vmodl.rb +1 -1
- data/devel/merge-manual-vmodl.rb +32 -0
- data/lib/rbvmomi/basic_types.rb +19 -3
- data/lib/rbvmomi/connection.rb +22 -8
- data/lib/rbvmomi/deserialization.rb +8 -2
- data/lib/rbvmomi/pbm.rb +66 -0
- data/lib/rbvmomi/sms.rb +61 -0
- data/lib/rbvmomi/sms/SmsStorageManager.rb +7 -0
- data/lib/rbvmomi/trivial_soap.rb +6 -1
- data/lib/rbvmomi/type_loader.rb +21 -1
- data/lib/rbvmomi/utils/admission_control.rb +13 -1
- data/lib/rbvmomi/utils/deploy.rb +21 -9
- data/lib/rbvmomi/utils/perfdump.rb +628 -0
- data/lib/rbvmomi/vim.rb +36 -3
- data/lib/rbvmomi/vim/Folder.rb +10 -0
- data/lib/rbvmomi/vim/ManagedObject.rb +6 -1
- data/lib/rbvmomi/vim/OvfManager.rb +95 -6
- data/lib/rbvmomi/vim/PerformanceManager.rb +38 -13
- data/lib/rbvmomi/vim/Task.rb +1 -1
- data/lib/rbvmomi/vim/VirtualMachine.rb +33 -18
- data/test/test_deserialization.rb +3 -0
- data/test/test_serialization.rb +2 -2
- data/vmodl.db +0 -0
- metadata +7 -2
data/lib/rbvmomi/vim.rb
CHANGED
@@ -13,6 +13,7 @@ class VIM < Connection
|
|
13
13
|
# @option opts [Numeric] :port (443) Port to connect to.
|
14
14
|
# @option opts [Boolean] :ssl (true) Whether to use SSL.
|
15
15
|
# @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
|
16
|
+
# @option opts [String] :cookie If set, use cookie to connect instead of user/password
|
16
17
|
# @option opts [String] :user (root) Username.
|
17
18
|
# @option opts [String] :password Password.
|
18
19
|
# @option opts [String] :path (/sdk) SDK endpoint path.
|
@@ -20,6 +21,7 @@ class VIM < Connection
|
|
20
21
|
def self.connect opts
|
21
22
|
fail unless opts.is_a? Hash
|
22
23
|
fail "host option required" unless opts[:host]
|
24
|
+
opts[:cookie] ||= nil
|
23
25
|
opts[:user] ||= 'root'
|
24
26
|
opts[:password] ||= ''
|
25
27
|
opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
|
@@ -32,10 +34,12 @@ class VIM < Connection
|
|
32
34
|
opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
|
33
35
|
|
34
36
|
new(opts).tap do |vim|
|
35
|
-
|
37
|
+
unless opts[:cookie]
|
38
|
+
vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
|
39
|
+
end
|
36
40
|
unless rev_given
|
37
41
|
rev = vim.serviceContent.about.apiVersion
|
38
|
-
vim.rev = [rev, '5.
|
42
|
+
vim.rev = [rev, '5.5'].min
|
39
43
|
end
|
40
44
|
end
|
41
45
|
end
|
@@ -45,7 +49,7 @@ class VIM < Connection
|
|
45
49
|
self.cookie = nil
|
46
50
|
super
|
47
51
|
end
|
48
|
-
|
52
|
+
|
49
53
|
def rev= x
|
50
54
|
super
|
51
55
|
@serviceContent = nil
|
@@ -86,6 +90,35 @@ class VIM < Connection
|
|
86
90
|
pp.text "VIM(#{@opts[:host]})"
|
87
91
|
end
|
88
92
|
|
93
|
+
def instanceUuid
|
94
|
+
serviceContent.about.instanceUuid
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_log_lines logKey, lines=5, start=nil, host=nil
|
98
|
+
diagMgr = self.serviceContent.diagnosticManager
|
99
|
+
if !start
|
100
|
+
log = diagMgr.BrowseDiagnosticLog(host: host, key: logKey, start: 999999999)
|
101
|
+
lineEnd = log.lineEnd
|
102
|
+
start = lineEnd - lines
|
103
|
+
end
|
104
|
+
start = start < 0 ? 0 : start
|
105
|
+
log = diagMgr.BrowseDiagnosticLog(host: host, key: logKey, start: start)
|
106
|
+
if log.lineText.size > 0
|
107
|
+
[log.lineText.slice(-lines, log.lineText.size), log.lineEnd]
|
108
|
+
else
|
109
|
+
[log.lineText, log.lineEnd]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def get_log_keys host=nil
|
114
|
+
diagMgr = self.serviceContent.diagnosticManager
|
115
|
+
keys = []
|
116
|
+
diagMgr.QueryDescriptions(host: host).each do |desc|
|
117
|
+
keys << "#{desc.key}"
|
118
|
+
end
|
119
|
+
keys
|
120
|
+
end
|
121
|
+
|
89
122
|
add_extension_dir File.join(File.dirname(__FILE__), "vim")
|
90
123
|
(ENV['RBVMOMI_VIM_EXTENSION_PATH']||'').split(':').each { |dir| add_extension_dir dir }
|
91
124
|
|
data/lib/rbvmomi/vim/Folder.rb
CHANGED
@@ -53,6 +53,16 @@ class RbVmomi::VIM::Folder
|
|
53
53
|
x if x.is_a? type
|
54
54
|
end
|
55
55
|
|
56
|
+
# Retrieve a managed entity by inventory path.
|
57
|
+
# @param path [String] A path of the form "My Folder/My Datacenter/vm/Discovered VM/VM1"
|
58
|
+
# @return [VIM::ManagedEntity]
|
59
|
+
def findByInventoryPath path
|
60
|
+
propSpecs = {
|
61
|
+
:entity => self, :inventoryPath => path
|
62
|
+
}
|
63
|
+
x = _connection.searchIndex.FindByInventoryPath(propSpecs)
|
64
|
+
end
|
65
|
+
|
56
66
|
# Alias to <tt>traverse path, type, true</tt>
|
57
67
|
# @see #traverse
|
58
68
|
def traverse! path, type=Object
|
@@ -35,7 +35,12 @@ class RbVmomi::VIM::ManagedObject
|
|
35
35
|
:type => self.class.wsdl_name
|
36
36
|
}]
|
37
37
|
}
|
38
|
-
_connection.propertyCollector.RetrieveProperties(:specSet => [spec])
|
38
|
+
ret = _connection.propertyCollector.RetrieveProperties(:specSet => [spec])
|
39
|
+
if ret && ret.length > 0
|
40
|
+
ret[0].to_hash
|
41
|
+
else
|
42
|
+
{}
|
43
|
+
end
|
39
44
|
end
|
40
45
|
|
41
46
|
# Efficiently retrieve multiple properties from an object.
|
@@ -48,7 +48,16 @@ class RbVmomi::VIM::OvfManager
|
|
48
48
|
result.warning.each{|x| puts "OVF Warning: #{x.localizedMessage.chomp}" }
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
importSpec = result.importSpec
|
52
|
+
if importSpec && importSpec.instantiationOst && importSpec.instantiationOst.child
|
53
|
+
importSpec.instantiationOst.child.each do |child|
|
54
|
+
child.section.map do |section|
|
55
|
+
section.xml = _handle_ost(section.xml, opts)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
nfcLease = opts[:resourcePool].ImportVApp(:spec => importSpec,
|
52
61
|
:folder => opts[:vmFolder],
|
53
62
|
:host => opts[:host])
|
54
63
|
|
@@ -56,9 +65,32 @@ class RbVmomi::VIM::OvfManager
|
|
56
65
|
raise nfcLease.error if nfcLease.state == "error"
|
57
66
|
begin
|
58
67
|
nfcLease.HttpNfcLeaseProgress(:percent => 5)
|
68
|
+
timeout, = nfcLease.collect 'info.leaseTimeout'
|
69
|
+
puts "DEBUG: Timeout: #{timeout}"
|
70
|
+
if timeout < 4 * 60
|
71
|
+
puts "WARNING: OVF upload NFC lease timeout less than 4 minutes"
|
72
|
+
end
|
59
73
|
progress = 5.0
|
60
74
|
result.fileItem.each do |fileItem|
|
61
|
-
|
75
|
+
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
76
|
+
# Retry nfcLease.collect because of PR 969599:
|
77
|
+
# If retrying property collector works, this means there is a network
|
78
|
+
# or VC overloading problem.
|
79
|
+
retrynum = 5
|
80
|
+
i = 1
|
81
|
+
while i <= retrynum && !leaseState
|
82
|
+
puts "Retrying at iteration #{i}"
|
83
|
+
sleep 1
|
84
|
+
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
85
|
+
i += 1
|
86
|
+
end
|
87
|
+
if leaseState != "ready"
|
88
|
+
raise "NFC lease is no longer ready: #{leaseState}: #{leaseError}"
|
89
|
+
end
|
90
|
+
if leaseInfo == nil
|
91
|
+
raise "NFC lease disappeared?"
|
92
|
+
end
|
93
|
+
deviceUrl = leaseInfo.deviceUrl.find{|x| x.importKey == fileItem.deviceId}
|
62
94
|
if !deviceUrl
|
63
95
|
raise "Couldn't find deviceURL for device '#{fileItem.deviceId}'"
|
64
96
|
end
|
@@ -74,12 +106,25 @@ class RbVmomi::VIM::OvfManager
|
|
74
106
|
|
75
107
|
keepAliveThread = Thread.new do
|
76
108
|
while true
|
77
|
-
sleep 2 * 60
|
78
109
|
nfcLease.HttpNfcLeaseProgress(:percent => progress.to_i)
|
110
|
+
sleep 1 * 60
|
79
111
|
end
|
80
112
|
end
|
81
113
|
|
82
|
-
|
114
|
+
i = 1
|
115
|
+
ip = nil
|
116
|
+
begin
|
117
|
+
begin
|
118
|
+
puts "Iteration #{i}: Trying to get host's IP address ..."
|
119
|
+
ip = opts[:host].config.network.vnic[0].spec.ip.ipAddress
|
120
|
+
rescue Exception=>e
|
121
|
+
puts "Iteration #{i}: Couldn't get host's IP address: #{e}"
|
122
|
+
end
|
123
|
+
sleep 1
|
124
|
+
i += 1
|
125
|
+
end while i <= 5 && !ip
|
126
|
+
raise "Couldn't get host's IP address" unless ip
|
127
|
+
href = deviceUrl.url.gsub("*", ip)
|
83
128
|
downloadCmd = "#{CURLBIN} -L '#{URI::escape(filename)}'"
|
84
129
|
uploadCmd = "#{CURLBIN} -Ss -X #{method} --insecure -T - -H 'Content-Type: application/x-vnd.vmware-streamVmdk' '#{URI::escape(href)}'"
|
85
130
|
# Previously we used to append "-H 'Content-Length: #{fileItem.size}'"
|
@@ -96,12 +141,56 @@ class RbVmomi::VIM::OvfManager
|
|
96
141
|
end
|
97
142
|
|
98
143
|
nfcLease.HttpNfcLeaseProgress(:percent => 100)
|
99
|
-
|
100
|
-
|
144
|
+
raise nfcLease.error if nfcLease.state == "error"
|
145
|
+
i = 1
|
146
|
+
vm = nil
|
147
|
+
begin
|
148
|
+
begin
|
149
|
+
puts "Iteration #{i}: Trying to access nfcLease.info.entity ..."
|
150
|
+
vm = nfcLease.info.entity
|
151
|
+
rescue Exception=>e
|
152
|
+
puts "Iteration #{i}: Couldn't access nfcLease.info.entity: #{e}"
|
153
|
+
end
|
154
|
+
sleep 1
|
155
|
+
i += 1
|
156
|
+
end while i <= 5 && !vm
|
157
|
+
raise "Couldn't access nfcLease.info.entity" unless vm
|
158
|
+
|
159
|
+
# Ignore sporadic connection errors caused by PR 1019166..
|
160
|
+
# Three attempts are made to execute HttpNfcLeaseComplete.
|
161
|
+
# Not critical if none goes through, as long as vm is obtained
|
162
|
+
#
|
163
|
+
# TODO: find the reason why HttpNfcLeaseComplete gets a wrong
|
164
|
+
# response (RetrievePropertiesResponse)
|
165
|
+
i = 0
|
166
|
+
begin
|
167
|
+
nfcLease.HttpNfcLeaseComplete
|
168
|
+
puts "HttpNfcLeaseComplete succeeded"
|
169
|
+
rescue RbVmomi::VIM::InvalidState
|
170
|
+
puts "HttpNfcLeaseComplete already finished.."
|
171
|
+
rescue Exception => e
|
172
|
+
puts "HttpNfcLeaseComplete failed at iteration #{i} with exception: #{e}"
|
173
|
+
i += 1
|
174
|
+
retry if i < 3
|
175
|
+
puts "Giving up HttpNfcLeaseComplete.."
|
176
|
+
end
|
101
177
|
vm
|
102
178
|
end
|
103
179
|
rescue Exception
|
104
180
|
(nfcLease.HttpNfcLeaseAbort rescue nil) if nfcLease
|
105
181
|
raise
|
106
182
|
end
|
183
|
+
|
184
|
+
def _handle_ost ost, opts = {}
|
185
|
+
ost = Nokogiri::XML(ost)
|
186
|
+
if opts[:vservice] == ['com.vmware.vim.vsm:extension_vservice']
|
187
|
+
ost.xpath('//vmw:Annotations/vmw:Providers/vmw:Provider').each do |x|
|
188
|
+
x['vmw:selected'] = 'selected'
|
189
|
+
end
|
190
|
+
ost.xpath('//vmw:Annotations/vmw:Providers').each do |x|
|
191
|
+
x['vmw:selected'] = 'com.vmware.vim.vsm:extension_vservice'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
ost.to_s
|
195
|
+
end
|
107
196
|
end
|
@@ -46,13 +46,21 @@ class RbVmomi::VIM::PerformanceManager
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
instances = opts[:instance] || '*'
|
50
|
+
if !instances.is_a?(Array)
|
51
|
+
instances = [instances]
|
52
|
+
end
|
53
|
+
metric_ids = []
|
54
|
+
metrics.each do |x|
|
50
55
|
counter = perfcounter_hash[x]
|
51
56
|
if !counter
|
52
57
|
pp perfcounter_hash.keys
|
53
58
|
fail "Counter for #{x} couldn't be found"
|
54
59
|
end
|
55
|
-
|
60
|
+
instances.each do |instance|
|
61
|
+
metric_ids << RbVmomi::VIM::PerfMetricId(:counterId => counter.key,
|
62
|
+
:instance => instance)
|
63
|
+
end
|
56
64
|
end
|
57
65
|
query_specs = objects.map do |obj|
|
58
66
|
RbVmomi::VIM::PerfQuerySpec({
|
@@ -65,19 +73,36 @@ class RbVmomi::VIM::PerformanceManager
|
|
65
73
|
end
|
66
74
|
stats = QueryPerf(:querySpec => query_specs)
|
67
75
|
|
68
|
-
|
69
|
-
[
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
[
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
if !opts[:multi_instance]
|
77
|
+
Hash[stats.map do |res|
|
78
|
+
[
|
79
|
+
res.entity,
|
80
|
+
{
|
81
|
+
:sampleInfo => res.sampleInfo,
|
82
|
+
:metrics => Hash[res.value.map do |metric|
|
83
|
+
metric_name = perfcounter_idhash[metric.id.counterId].name
|
84
|
+
[metric_name, metric.value]
|
85
|
+
end]
|
86
|
+
}
|
87
|
+
]
|
88
|
+
end]
|
89
|
+
else
|
90
|
+
Hash[stats.map do |res|
|
91
|
+
[
|
92
|
+
res.entity,
|
93
|
+
{
|
94
|
+
:sampleInfo => res.sampleInfo,
|
95
|
+
:metrics => Hash[res.value.map do |metric|
|
96
|
+
metric_name = perfcounter_idhash[metric.id.counterId].name
|
97
|
+
[[metric_name, metric.id.instance], metric.value]
|
98
|
+
end]
|
99
|
+
}
|
100
|
+
]
|
101
|
+
end]
|
102
|
+
end
|
79
103
|
end
|
80
104
|
|
105
|
+
|
81
106
|
def active_intervals
|
82
107
|
intervals = historicalInterval
|
83
108
|
Hash[(1..4).map { |level| [level, intervals.select { |x| x.enabled && x.level >= level }] }]
|
data/lib/rbvmomi/vim/Task.rb
CHANGED
@@ -54,7 +54,7 @@ class RbVmomi::VIM::Task
|
|
54
54
|
def child_tasks
|
55
55
|
tm = _connection.serviceContent.taskManager
|
56
56
|
col = tm.CreateCollectorForTasks(:filter => {
|
57
|
-
:rootTaskKey => self.info.key
|
57
|
+
:rootTaskKey => [self.info.key],
|
58
58
|
})
|
59
59
|
# XXX: Likely this is not enough and we need to collect pages other
|
60
60
|
# than the latest.
|
@@ -34,26 +34,41 @@ class RbVmomi::VIM::VirtualMachine
|
|
34
34
|
def add_delta_disk_layer_on_all_disks
|
35
35
|
devices, = self.collect 'config.hardware.device'
|
36
36
|
disks = devices.grep(RbVmomi::VIM::VirtualDisk)
|
37
|
-
|
37
|
+
spec = update_spec_add_delta_disk_layer_on_all_disks
|
38
|
+
self.ReconfigVM_Task(:spec => spec).wait_for_completion
|
39
|
+
end
|
40
|
+
|
41
|
+
# Updates a passed in spec to perform the task of adding a delta disk layer
|
42
|
+
# on top of all disks. Does the same as add_delta_disk_layer_on_all_disks
|
43
|
+
# but instead of issuing the ReconfigVM_Task, it just constructs the
|
44
|
+
# spec, so that the caller can batch a couple of updates into one
|
45
|
+
# ReconfigVM_Task.
|
46
|
+
def update_spec_add_delta_disk_layer_on_all_disks spec = {}
|
47
|
+
devices, = self.collect 'config.hardware.device'
|
48
|
+
disks = devices.grep(RbVmomi::VIM::VirtualDisk)
|
49
|
+
device_change = []
|
38
50
|
disks.each do |disk|
|
39
|
-
|
40
|
-
:
|
41
|
-
|
42
|
-
:operation => :remove,
|
43
|
-
:device => disk
|
44
|
-
},
|
45
|
-
{
|
46
|
-
:operation => :add,
|
47
|
-
:fileOperation => :create,
|
48
|
-
:device => disk.dup.tap { |x|
|
49
|
-
x.backing = x.backing.dup
|
50
|
-
x.backing.fileName = "[#{disk.backing.datastore.name}]"
|
51
|
-
x.backing.parent = disk.backing
|
52
|
-
},
|
53
|
-
}
|
54
|
-
]
|
51
|
+
device_change << {
|
52
|
+
:operation => :remove,
|
53
|
+
:device => disk
|
55
54
|
}
|
56
|
-
|
55
|
+
device_change << {
|
56
|
+
:operation => :add,
|
57
|
+
:fileOperation => :create,
|
58
|
+
:device => disk.dup.tap { |x|
|
59
|
+
x.backing = x.backing.dup
|
60
|
+
x.backing.fileName = "[#{disk.backing.datastore.name}]"
|
61
|
+
x.backing.parent = disk.backing
|
62
|
+
},
|
63
|
+
}
|
64
|
+
end
|
65
|
+
if spec.is_a?(RbVmomi::VIM::VirtualMachineConfigSpec)
|
66
|
+
spec.deviceChange ||= []
|
67
|
+
spec.deviceChange += device_change
|
68
|
+
else
|
69
|
+
spec[:deviceChange] ||= []
|
70
|
+
spec[:deviceChange] += device_change
|
57
71
|
end
|
72
|
+
spec
|
58
73
|
end
|
59
74
|
end
|
@@ -252,11 +252,14 @@ end
|
|
252
252
|
:connectionState => "connected",
|
253
253
|
:dynamicProperty => [],
|
254
254
|
:faultToleranceState => "notConfigured",
|
255
|
+
:featureMask => [],
|
256
|
+
:featureRequirement => [],
|
255
257
|
:host => VIM::HostSystem(nil, "host-32"),
|
256
258
|
:maxCpuUsage => 5612,
|
257
259
|
:maxMemoryUsage => 3072,
|
258
260
|
:memoryOverhead => 128671744,
|
259
261
|
:numMksConnections => 1,
|
262
|
+
:offlineFeatureRequirement => [],
|
260
263
|
:powerState => "poweredOn",
|
261
264
|
:recordReplayState => "inactive",
|
262
265
|
:suspendInterval => 0,
|
data/test/test_serialization.rb
CHANGED
@@ -287,9 +287,9 @@ class SerializationTest < Test::Unit::TestCase
|
|
287
287
|
end
|
288
288
|
|
289
289
|
def test_time
|
290
|
-
obj = Time.at
|
290
|
+
obj = Time.at(DateTime.new(2011, 11, 16, 13, 36, 8, Rational(-8,24)).strftime("%s").to_i).getgm
|
291
291
|
check <<-EOS, obj, 'xsd:dateTime', false
|
292
|
-
<root>2011-11-
|
292
|
+
<root>2011-11-16T21:36:08Z</root>
|
293
293
|
EOS
|
294
294
|
end
|
295
295
|
|
data/vmodl.db
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbvmomi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-12-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- devel/benchmark.rb
|
81
81
|
- devel/collisions.rb
|
82
82
|
- devel/merge-internal-vmodl.rb
|
83
|
+
- devel/merge-manual-vmodl.rb
|
83
84
|
- examples/annotate.rb
|
84
85
|
- examples/cached_ovf_deploy.rb
|
85
86
|
- examples/clone_vm.rb
|
@@ -102,12 +103,16 @@ files:
|
|
102
103
|
- lib/rbvmomi/connection.rb
|
103
104
|
- lib/rbvmomi/deserialization.rb
|
104
105
|
- lib/rbvmomi/fault.rb
|
106
|
+
- lib/rbvmomi/pbm.rb
|
107
|
+
- lib/rbvmomi/sms.rb
|
108
|
+
- lib/rbvmomi/sms/SmsStorageManager.rb
|
105
109
|
- lib/rbvmomi/trivial_soap.rb
|
106
110
|
- lib/rbvmomi/trollop.rb
|
107
111
|
- lib/rbvmomi/type_loader.rb
|
108
112
|
- lib/rbvmomi/utils/admission_control.rb
|
109
113
|
- lib/rbvmomi/utils/deploy.rb
|
110
114
|
- lib/rbvmomi/utils/leases.rb
|
115
|
+
- lib/rbvmomi/utils/perfdump.rb
|
111
116
|
- lib/rbvmomi/vim.rb
|
112
117
|
- lib/rbvmomi/vim/ComputeResource.rb
|
113
118
|
- lib/rbvmomi/vim/Datacenter.rb
|