rbvmomi2 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -25
- data/exe/rbvmomish +50 -48
- data/lib/rbvmomi/basic_types.rb +318 -294
- data/lib/rbvmomi/connection.rb +221 -216
- data/lib/rbvmomi/deserialization.rb +201 -205
- data/lib/rbvmomi/fault.rb +10 -9
- data/lib/rbvmomi/optimist.rb +51 -50
- data/lib/rbvmomi/pbm.rb +52 -50
- data/lib/rbvmomi/sms/SmsStorageManager.rb +2 -1
- data/lib/rbvmomi/sms.rb +48 -46
- data/lib/rbvmomi/sso.rb +13 -18
- data/lib/rbvmomi/trivial_soap.rb +9 -8
- data/lib/rbvmomi/type_loader.rb +100 -101
- data/lib/rbvmomi/utils/admission_control.rb +90 -106
- data/lib/rbvmomi/utils/deploy.rb +77 -85
- data/lib/rbvmomi/utils/leases.rb +31 -33
- data/lib/rbvmomi/utils/perfdump.rb +177 -207
- data/lib/rbvmomi/version.rb +2 -1
- data/lib/rbvmomi/vim/ComputeResource.rb +17 -15
- data/lib/rbvmomi/vim/Datacenter.rb +1 -0
- data/lib/rbvmomi/vim/Datastore.rb +18 -15
- data/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb +7 -6
- data/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb +3 -2
- data/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb +7 -6
- data/lib/rbvmomi/vim/Folder.rb +37 -33
- data/lib/rbvmomi/vim/HostSystem.rb +139 -136
- data/lib/rbvmomi/vim/ManagedEntity.rb +15 -14
- data/lib/rbvmomi/vim/ManagedObject.rb +11 -10
- data/lib/rbvmomi/vim/ObjectContent.rb +3 -1
- data/lib/rbvmomi/vim/ObjectUpdate.rb +3 -1
- data/lib/rbvmomi/vim/OvfManager.rb +50 -57
- data/lib/rbvmomi/vim/PerfCounterInfo.rb +4 -3
- data/lib/rbvmomi/vim/PerformanceManager.rb +28 -31
- data/lib/rbvmomi/vim/PropertyCollector.rb +8 -7
- data/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb +22 -21
- data/lib/rbvmomi/vim/ResourcePool.rb +19 -18
- data/lib/rbvmomi/vim/ServiceInstance.rb +8 -7
- data/lib/rbvmomi/vim/Task.rb +6 -5
- data/lib/rbvmomi/vim/VirtualMachine.rb +8 -7
- data/lib/rbvmomi/vim.rb +112 -129
- data/lib/rbvmomi.rb +1 -0
- metadata +54 -10
@@ -1,177 +1,180 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
3
|
# SPDX-License-Identifier: MIT
|
3
4
|
|
4
5
|
module RbVmomi
|
5
6
|
|
6
|
-
class VIM::HostSystem
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
class VIM::HostSystem
|
8
|
+
def esxcli
|
9
|
+
@cached_esxcli ||= VIM::EsxcliNamespace.root(self)
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def dtm
|
13
|
+
@cached_dtm ||= begin
|
14
|
+
RetrieveDynamicTypeManager()
|
15
|
+
rescue VIM::MethodNotFound
|
16
|
+
if summary.config.product.version >= '4.1.0'
|
17
|
+
if summary.config.product.version < '5.0.0' and direct?
|
18
|
+
VIM::InternalDynamicTypeManager(_connection, 'ha-dynamic-type-manager')
|
19
|
+
else
|
20
|
+
raise 'esxcli not supported through VC before 5.0.0'
|
21
|
+
end
|
18
22
|
else
|
19
|
-
raise
|
23
|
+
raise 'esxcli not supported before 4.1.0'
|
20
24
|
end
|
21
|
-
else
|
22
|
-
raise "esxcli not supported before 4.1.0"
|
23
25
|
end
|
24
|
-
|
25
|
-
end
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
def dti
|
29
|
+
@cached_dti ||= dtm.DynamicTypeMgrQueryTypeInfo
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def create_dynamic_managed_object inst
|
33
|
+
wsdlName = dti.managedTypeInfo.find { |x| x.name == inst.moType }.wsdlName
|
34
|
+
_connection.type(wsdlName).new(_connection, inst.id)
|
35
|
+
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
inst = dtm.DynamicTypeMgrQueryMoInstances.find { |x| x.moType == 'vim.CLIInfo' }
|
40
|
-
@cached_cli_info_fetcher = create_dynamic_managed_object inst
|
41
|
-
end
|
37
|
+
def cli_info_fetcher
|
38
|
+
# XXX there can be more than one
|
39
|
+
return @cached_cli_info_fetcher if @cached_cli_info_fetcher
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
inst = dtm.DynamicTypeMgrQueryMoInstances.find { |x| x.moType == 'vim.CLIInfo' }
|
42
|
+
@cached_cli_info_fetcher = create_dynamic_managed_object inst
|
43
|
+
end
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
45
|
+
def mme
|
46
|
+
@cached_mme ||= RetrieveManagedMethodExecuter()
|
47
|
+
end
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
attr_reader :name, :parent, :host, :type, :instance, :type_info, :namespaces, :commands
|
56
|
-
|
57
|
-
def self.root host
|
58
|
-
type_hash = host.dti.toRbvmomiTypeHash
|
59
|
-
VIM.loader.add_types type_hash
|
60
|
-
all_instances = host.dtm.DynamicTypeMgrQueryMoInstances
|
61
|
-
instances = Hash[all_instances.select { |x| x.moType.start_with? ESXCLI_PREFIX }.
|
62
|
-
map { |x| [x.moType,x.id] }]
|
63
|
-
type_infos = Hash[host.dti.managedTypeInfo.map { |x| [x.name,x] }]
|
64
|
-
new('root', nil, host).tap do |root|
|
65
|
-
instances.each do |type,instance|
|
66
|
-
path = type.split('.')[2..-1]
|
67
|
-
ns = path.inject(root) { |b,v| b.namespaces[v] }
|
68
|
-
ns.realize type, instance, type_infos[type]
|
69
|
-
end
|
49
|
+
def direct?
|
50
|
+
@ref == 'ha-host'
|
70
51
|
end
|
71
52
|
end
|
72
53
|
|
73
|
-
|
74
|
-
|
75
|
-
@parent = parent
|
76
|
-
@host = host
|
77
|
-
@type = nil
|
78
|
-
@instance = nil
|
79
|
-
@type_info = nil
|
80
|
-
@namespaces = Hash.new { |h,k| h[k] = self.class.new k, self, host }
|
81
|
-
@commands = {}
|
82
|
-
@cached_cli_info = nil
|
83
|
-
end
|
54
|
+
class VIM::EsxcliNamespace
|
55
|
+
ESXCLI_PREFIX = 'vim.EsxCLI.'
|
84
56
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
57
|
+
attr_reader :name, :parent, :host, :type, :instance, :type_info, :namespaces, :commands
|
58
|
+
|
59
|
+
def self.root host
|
60
|
+
type_hash = host.dti.toRbvmomiTypeHash
|
61
|
+
VIM.loader.add_types type_hash
|
62
|
+
all_instances = host.dtm.DynamicTypeMgrQueryMoInstances
|
63
|
+
instances = Hash[all_instances.select { |x| x.moType.start_with? ESXCLI_PREFIX }.
|
64
|
+
map { |x| [x.moType, x.id] }]
|
65
|
+
type_infos = Hash[host.dti.managedTypeInfo.map { |x| [x.name, x] }]
|
66
|
+
new('root', nil, host).tap do |root|
|
67
|
+
instances.each do |type, instance|
|
68
|
+
path = type.split('.')[2..-1]
|
69
|
+
ns = path.inject(root) { |b, v| b.namespaces[v] }
|
70
|
+
ns.realize type, instance, type_infos[type]
|
71
|
+
end
|
72
|
+
end
|
93
73
|
end
|
94
|
-
end
|
95
74
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
75
|
+
def initialize name, parent, host
|
76
|
+
@name = name
|
77
|
+
@parent = parent
|
78
|
+
@host = host
|
79
|
+
@type = nil
|
80
|
+
@instance = nil
|
81
|
+
@type_info = nil
|
82
|
+
@namespaces = Hash.new { |h, k| h[k] = self.class.new k, self, host }
|
83
|
+
@commands = {}
|
84
|
+
@cached_cli_info = nil
|
100
85
|
end
|
101
|
-
end
|
102
86
|
|
103
|
-
|
104
|
-
|
105
|
-
if @host.direct?
|
106
|
-
@host.cli_info_fetcher.VimCLIInfoFetchCLIInfo(:typeName => type_name)
|
107
|
-
else
|
108
|
-
@host.mme.execute(@host.cli_info_fetcher._ref,
|
109
|
-
"vim.CLIInfo.FetchCLIInfo", :typeName => type_name)
|
110
|
-
end
|
111
|
-
end
|
87
|
+
def realize type, instance, type_info
|
88
|
+
raise if @type or @instance
|
112
89
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
90
|
+
@type = type
|
91
|
+
@instance = instance
|
92
|
+
@type_info = type_info
|
93
|
+
@type_info.method.each do |method_type_info|
|
94
|
+
name = method_type_info.name
|
95
|
+
@commands[name] = VIM::EsxcliCommand.new self, method_type_info
|
96
|
+
end
|
97
|
+
end
|
117
98
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
@commands[name].call(*args)
|
124
|
-
else
|
125
|
-
raise NoMethodError
|
99
|
+
def type_name
|
100
|
+
if @type then @type
|
101
|
+
elsif @parent then "#{@parent.type_name}.#{@name}"
|
102
|
+
else 'vim.EsxCLI'
|
103
|
+
end
|
126
104
|
end
|
127
|
-
end
|
128
105
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
q.text '{'
|
134
|
-
q.breakable
|
135
|
-
items = (@namespaces.values+@commands.values).sort_by(&:name)
|
136
|
-
q.seplist items, nil, :each do |v|
|
137
|
-
if v.is_a? VIM::EsxcliNamespace
|
138
|
-
q.pp v
|
106
|
+
def cli_info
|
107
|
+
@cached_cli_info ||=
|
108
|
+
if @host.direct?
|
109
|
+
@host.cli_info_fetcher.VimCLIInfoFetchCLIInfo(typeName: type_name)
|
139
110
|
else
|
140
|
-
|
111
|
+
@host.mme.execute(@host.cli_info_fetcher._ref,
|
112
|
+
'vim.CLIInfo.FetchCLIInfo', typeName: type_name)
|
141
113
|
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def obj
|
117
|
+
conn = @host._connection
|
118
|
+
conn.type(@type_info.wsdlName).new(conn, @instance)
|
119
|
+
end
|
120
|
+
|
121
|
+
def method_missing(name, *args)
|
122
|
+
name = name.to_s
|
123
|
+
if @namespaces.member? name and args.empty?
|
124
|
+
@namespaces[name]
|
125
|
+
elsif @commands.member? name
|
126
|
+
@commands[name].call(*args)
|
127
|
+
else
|
128
|
+
raise NoMethodError
|
142
129
|
end
|
143
130
|
end
|
144
|
-
|
145
|
-
q
|
131
|
+
|
132
|
+
def pretty_print q
|
133
|
+
q.text @name
|
134
|
+
q.text ' '
|
135
|
+
q.group 2 do
|
136
|
+
q.text '{'
|
137
|
+
q.breakable
|
138
|
+
items = (@namespaces.values+@commands.values).sort_by(&:name)
|
139
|
+
q.seplist items, nil, :each do |v|
|
140
|
+
if v.is_a? VIM::EsxcliNamespace
|
141
|
+
q.pp v
|
142
|
+
else
|
143
|
+
q.text v.name
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
q.breakable
|
148
|
+
q.text '}'
|
149
|
+
end
|
146
150
|
end
|
147
|
-
end
|
148
151
|
|
149
|
-
class VIM::EsxcliCommand
|
150
|
-
|
152
|
+
class VIM::EsxcliCommand
|
153
|
+
attr_reader :ns, :type_info, :cli_info
|
151
154
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
155
|
+
def initialize ns, type_info
|
156
|
+
@ns = ns
|
157
|
+
@type_info = type_info
|
158
|
+
@cached_cli_info = nil
|
159
|
+
end
|
157
160
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
+
def name
|
162
|
+
@type_info.name
|
163
|
+
end
|
161
164
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
+
def cli_info
|
166
|
+
@cached_cli_info ||= @ns.cli_info.method.find { |x| x.name == @type_info.name }
|
167
|
+
end
|
165
168
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
169
|
+
def call args={}
|
170
|
+
if @ns.host.direct?
|
171
|
+
@ns.obj._call @type_info.wsdlName, args
|
172
|
+
else
|
173
|
+
real_args = Set.new(type_info.paramTypeInfo.map(&:name))
|
174
|
+
args = args.reject { |k, v| !real_args.member?(k.to_s) }
|
175
|
+
@ns.host.mme.execute(@ns.obj._ref, "#{@ns.type_name}.#{@type_info.name}", args)
|
176
|
+
end
|
173
177
|
end
|
174
178
|
end
|
175
|
-
end
|
176
179
|
|
177
180
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
3
|
# SPDX-License-Identifier: MIT
|
3
4
|
|
@@ -7,35 +8,35 @@ class RbVmomi::VIM::ManagedEntity
|
|
7
8
|
def path
|
8
9
|
self.class.paths([self])[self]
|
9
10
|
end
|
10
|
-
|
11
|
+
|
11
12
|
# Retrieve the ancestors of a list of entries.
|
12
13
|
# @return [Hash] Object-indexed hash of ancestors of entities, starting with the root.
|
13
14
|
def self.paths objs
|
14
15
|
filterSpec = RbVmomi::VIM.PropertyFilterSpec(
|
15
|
-
:
|
16
|
+
objectSet: objs.map do |obj|
|
16
17
|
RbVmomi::VIM.ObjectSpec(
|
17
|
-
:
|
18
|
-
:
|
18
|
+
obj: obj,
|
19
|
+
selectSet: [
|
19
20
|
RbVmomi::VIM.TraversalSpec(
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
RbVmomi::VIM.SelectionSpec(:
|
21
|
+
name: 'tsME',
|
22
|
+
type: 'ManagedEntity',
|
23
|
+
path: 'parent',
|
24
|
+
skip: false,
|
25
|
+
selectSet: [
|
26
|
+
RbVmomi::VIM.SelectionSpec(name: 'tsME')
|
26
27
|
]
|
27
28
|
)
|
28
29
|
]
|
29
30
|
)
|
30
31
|
end,
|
31
|
-
:
|
32
|
-
:
|
33
|
-
:
|
32
|
+
propSet: [{
|
33
|
+
pathSet: %w(name parent),
|
34
|
+
type: 'ManagedEntity'
|
34
35
|
}]
|
35
36
|
)
|
36
37
|
|
37
38
|
propCollector = objs.first._connection.propertyCollector
|
38
|
-
result = propCollector.RetrieveProperties(:
|
39
|
+
result = propCollector.RetrieveProperties(specSet: [filterSpec])
|
39
40
|
|
40
41
|
Hash[objs.map do |obj|
|
41
42
|
tree = {}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
3
|
# SPDX-License-Identifier: MIT
|
3
4
|
|
@@ -11,13 +12,13 @@ class RbVmomi::VIM::ManagedObject
|
|
11
12
|
# @todo Pass the current property values to the block.
|
12
13
|
def wait_until *pathSet, &b
|
13
14
|
all = pathSet.empty?
|
14
|
-
filter = _connection.propertyCollector.CreateFilter :
|
15
|
-
:
|
16
|
-
:
|
17
|
-
}, :
|
15
|
+
filter = _connection.propertyCollector.CreateFilter spec: {
|
16
|
+
propSet: [{ type: self.class.wsdl_name, all: all, pathSet: pathSet }],
|
17
|
+
objectSet: [{ obj: self }],
|
18
|
+
}, partialUpdates: false
|
18
19
|
ver = ''
|
19
20
|
loop do
|
20
|
-
result = _connection.propertyCollector.WaitForUpdates(:
|
21
|
+
result = _connection.propertyCollector.WaitForUpdates(version: ver)
|
21
22
|
ver = result.version
|
22
23
|
if x = b.call
|
23
24
|
return x
|
@@ -32,13 +33,13 @@ class RbVmomi::VIM::ManagedObject
|
|
32
33
|
# @return [Hash] Hash from property paths to values.
|
33
34
|
def collect! *pathSet
|
34
35
|
spec = {
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
36
|
+
objectSet: [{ obj: self }],
|
37
|
+
propSet: [{
|
38
|
+
pathSet: pathSet,
|
39
|
+
type: self.class.wsdl_name
|
39
40
|
}]
|
40
41
|
}
|
41
|
-
ret = _connection.propertyCollector.RetrieveProperties(:
|
42
|
+
ret = _connection.propertyCollector.RetrieveProperties(specSet: [spec])
|
42
43
|
if ret && ret.length > 0
|
43
44
|
ret[0].to_hash
|
44
45
|
else
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
3
|
# SPDX-License-Identifier: MIT
|
3
4
|
|
@@ -18,7 +19,8 @@ class RbVmomi::VIM::ObjectContent
|
|
18
19
|
def to_hash_uncached
|
19
20
|
h = {}
|
20
21
|
propSet.each do |x|
|
21
|
-
|
22
|
+
raise if h.member? x.name
|
23
|
+
|
22
24
|
h[x.name] = x.val
|
23
25
|
end
|
24
26
|
h
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
3
|
# SPDX-License-Identifier: MIT
|
3
4
|
|
@@ -18,7 +19,8 @@ class RbVmomi::VIM::ObjectUpdate
|
|
18
19
|
def to_hash_uncached
|
19
20
|
h = {}
|
20
21
|
changeSet.each do |x|
|
21
|
-
|
22
|
+
raise if h.member? x.name
|
23
|
+
|
22
24
|
h[x.name] = x.val
|
23
25
|
end
|
24
26
|
h
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
3
|
# SPDX-License-Identifier: MIT
|
3
4
|
|
@@ -5,7 +6,7 @@
|
|
5
6
|
# then set the +CURL+ environment variable to point to it.
|
6
7
|
# @todo Use an HTTP library instead of executing +curl+.
|
7
8
|
class RbVmomi::VIM::OvfManager
|
8
|
-
CURLBIN = ENV['CURL'] ||
|
9
|
+
CURLBIN = ENV['CURL'] || 'curl' #@private
|
9
10
|
|
10
11
|
# Deploy an OVF.
|
11
12
|
#
|
@@ -21,36 +22,34 @@ class RbVmomi::VIM::OvfManager
|
|
21
22
|
# @option opts [Hash] :propertyMappings Property mappings.
|
22
23
|
# @option opts [String] :deploymentOption Deployment option key.
|
23
24
|
def deployOVF opts
|
24
|
-
opts = { :
|
25
|
-
:
|
26
|
-
:
|
25
|
+
opts = { networkMappings: {},
|
26
|
+
propertyMappings: {},
|
27
|
+
diskProvisioning: :thin }.merge opts
|
27
28
|
|
28
29
|
%w(uri vmName vmFolder host resourcePool datastore).each do |k|
|
29
|
-
|
30
|
+
raise "parameter #{k} required" unless opts[k.to_sym]
|
30
31
|
end
|
31
32
|
|
32
33
|
ovfImportSpec = RbVmomi::VIM::OvfCreateImportSpecParams(
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
34
|
+
hostSystem: opts[:host],
|
35
|
+
locale: 'US',
|
36
|
+
entityName: opts[:vmName],
|
37
|
+
deploymentOption: opts[:deploymentOption] || '',
|
38
|
+
networkMapping: opts[:networkMappings].map{ |from, to| RbVmomi::VIM::OvfNetworkMapping(name: from, network: to) },
|
39
|
+
propertyMapping: opts[:propertyMappings].to_a,
|
40
|
+
diskProvisioning: opts[:diskProvisioning]
|
40
41
|
)
|
41
42
|
|
42
43
|
result = CreateImportSpec(
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
44
|
+
ovfDescriptor: open(opts[:uri]).read,
|
45
|
+
resourcePool: opts[:resourcePool],
|
46
|
+
datastore: opts[:datastore],
|
47
|
+
cisp: ovfImportSpec
|
47
48
|
)
|
48
49
|
|
49
50
|
raise result.error[0].localizedMessage if result.error && !result.error.empty?
|
50
51
|
|
51
|
-
if result.warning
|
52
|
-
result.warning.each{|x| puts "OVF Warning: #{x.localizedMessage.chomp}" }
|
53
|
-
end
|
52
|
+
result.warning.each{ |x| puts "OVF Warning: #{x.localizedMessage.chomp}" } if result.warning
|
54
53
|
|
55
54
|
importSpec = result.importSpec
|
56
55
|
if importSpec && importSpec.instantiationOst && importSpec.instantiationOst.child
|
@@ -60,20 +59,19 @@ class RbVmomi::VIM::OvfManager
|
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
63
|
-
|
64
|
-
nfcLease = opts[:resourcePool].ImportVApp(:spec => importSpec,
|
65
|
-
:folder => opts[:vmFolder],
|
66
|
-
:host => opts[:host])
|
67
62
|
|
68
|
-
nfcLease.
|
69
|
-
|
63
|
+
nfcLease = opts[:resourcePool].ImportVApp(spec: importSpec,
|
64
|
+
folder: opts[:vmFolder],
|
65
|
+
host: opts[:host])
|
66
|
+
|
67
|
+
nfcLease.wait_until(:state) { nfcLease.state != 'initializing' }
|
68
|
+
raise nfcLease.error if nfcLease.state == 'error'
|
69
|
+
|
70
70
|
begin
|
71
|
-
nfcLease.HttpNfcLeaseProgress(:
|
71
|
+
nfcLease.HttpNfcLeaseProgress(percent: 5)
|
72
72
|
timeout, = nfcLease.collect 'info.leaseTimeout'
|
73
73
|
puts "DEBUG: Timeout: #{timeout}"
|
74
|
-
if timeout < 4 * 60
|
75
|
-
puts "WARNING: OVF upload NFC lease timeout less than 4 minutes"
|
76
|
-
end
|
74
|
+
puts 'WARNING: OVF upload NFC lease timeout less than 4 minutes' if timeout < 4 * 60
|
77
75
|
progress = 5.0
|
78
76
|
result.fileItem.each do |fileItem|
|
79
77
|
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
@@ -88,33 +86,26 @@ class RbVmomi::VIM::OvfManager
|
|
88
86
|
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
89
87
|
i += 1
|
90
88
|
end
|
91
|
-
if leaseState !=
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
97
|
-
deviceUrl = leaseInfo.deviceUrl.find{|x| x.importKey == fileItem.deviceId}
|
98
|
-
if !deviceUrl
|
99
|
-
raise "Couldn't find deviceURL for device '#{fileItem.deviceId}'"
|
100
|
-
end
|
89
|
+
raise "NFC lease is no longer ready: #{leaseState}: #{leaseError}" if leaseState != 'ready'
|
90
|
+
raise 'NFC lease disappeared?' if leaseInfo == nil
|
91
|
+
|
92
|
+
deviceUrl = leaseInfo.deviceUrl.find{ |x| x.importKey == fileItem.deviceId }
|
93
|
+
raise "Couldn't find deviceURL for device '#{fileItem.deviceId}'" if !deviceUrl
|
101
94
|
|
102
95
|
ovfFilename = opts[:uri].to_s
|
103
96
|
tmp = ovfFilename.split(/\//)
|
104
97
|
tmp.pop
|
105
98
|
tmp << fileItem.path
|
106
|
-
filename = tmp.join(
|
99
|
+
filename = tmp.join('/')
|
107
100
|
|
108
101
|
# If filename doesn't have a URI scheme, we're considering it a local file
|
109
|
-
if URI(filename).scheme.nil?
|
110
|
-
filename = "file://" + filename
|
111
|
-
end
|
102
|
+
filename = 'file://' + filename if URI(filename).scheme.nil?
|
112
103
|
|
113
|
-
method = fileItem.create ?
|
104
|
+
method = fileItem.create ? 'PUT' : 'POST'
|
114
105
|
|
115
106
|
keepAliveThread = Thread.new do
|
116
107
|
while true
|
117
|
-
nfcLease.HttpNfcLeaseProgress(:
|
108
|
+
nfcLease.HttpNfcLeaseProgress(percent: progress.to_i)
|
118
109
|
sleep 1 * 60
|
119
110
|
end
|
120
111
|
end
|
@@ -132,24 +123,26 @@ class RbVmomi::VIM::OvfManager
|
|
132
123
|
i += 1
|
133
124
|
end while i <= 5 && !ip
|
134
125
|
raise "Couldn't get host's IP address" unless ip
|
135
|
-
|
126
|
+
|
127
|
+
href = deviceUrl.url.gsub('*', ip)
|
136
128
|
downloadCmd = "#{CURLBIN} -L '#{URI::escape(filename)}'"
|
137
129
|
uploadCmd = "#{CURLBIN} -Ss -X #{method} --insecure -T - -H 'Content-Type: application/x-vnd.vmware-streamVmdk' '#{URI::escape(href)}'"
|
138
130
|
# Previously we used to append "-H 'Content-Length: #{fileItem.size}'"
|
139
|
-
# to the uploadCmd. It is not clear to me why, but that leads to
|
131
|
+
# to the uploadCmd. It is not clear to me why, but that leads to
|
140
132
|
# trucation of the uploaded disk. Without this option curl can't tell
|
141
133
|
# the progress, but who cares
|
142
|
-
system("#{downloadCmd} | #{uploadCmd}", :
|
143
|
-
|
134
|
+
system("#{downloadCmd} | #{uploadCmd}", out: '/dev/null')
|
135
|
+
|
144
136
|
keepAliveThread.kill
|
145
137
|
keepAliveThread.join
|
146
|
-
|
138
|
+
|
147
139
|
progress += (90.0 / result.fileItem.length)
|
148
|
-
nfcLease.HttpNfcLeaseProgress(:
|
140
|
+
nfcLease.HttpNfcLeaseProgress(percent: progress.to_i)
|
149
141
|
end
|
150
142
|
|
151
|
-
nfcLease.HttpNfcLeaseProgress(:
|
152
|
-
raise nfcLease.error if nfcLease.state ==
|
143
|
+
nfcLease.HttpNfcLeaseProgress(percent: 100)
|
144
|
+
raise nfcLease.error if nfcLease.state == 'error'
|
145
|
+
|
153
146
|
i = 1
|
154
147
|
vm = nil
|
155
148
|
begin
|
@@ -173,14 +166,14 @@ class RbVmomi::VIM::OvfManager
|
|
173
166
|
i = 0
|
174
167
|
begin
|
175
168
|
nfcLease.HttpNfcLeaseComplete
|
176
|
-
puts
|
169
|
+
puts 'HttpNfcLeaseComplete succeeded'
|
177
170
|
rescue RbVmomi::VIM::InvalidState
|
178
|
-
puts
|
171
|
+
puts 'HttpNfcLeaseComplete already finished..'
|
179
172
|
rescue Exception => e
|
180
173
|
puts "HttpNfcLeaseComplete failed at iteration #{i} with exception: #{e}"
|
181
174
|
i += 1
|
182
175
|
retry if i < 3
|
183
|
-
puts
|
176
|
+
puts 'Giving up HttpNfcLeaseComplete..'
|
184
177
|
end
|
185
178
|
vm
|
186
179
|
end
|
@@ -188,7 +181,7 @@ class RbVmomi::VIM::OvfManager
|
|
188
181
|
(nfcLease.HttpNfcLeaseAbort rescue nil) if nfcLease
|
189
182
|
raise
|
190
183
|
end
|
191
|
-
|
184
|
+
|
192
185
|
def _handle_ost ost, opts = {}
|
193
186
|
ost = Nokogiri::XML(ost)
|
194
187
|
if opts[:vservice] == ['com.vmware.vim.vsm:extension_vservice']
|
@@ -1,17 +1,18 @@
|
|
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
|
+
#
|
5
6
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
7
|
# of this software and associated documentation files (the "Software"), to deal
|
7
8
|
# in the Software without restriction, including without limitation the rights
|
8
9
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
10
|
# copies of the Software, and to permit persons to whom the Software is
|
10
11
|
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
+
#
|
12
13
|
# The above copyright notice and this permission notice shall be included in
|
13
14
|
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
+
#
|
15
16
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
17
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
18
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|