ovfparse 0.9.0 → 0.9.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.
- data/lib/ovfparse/vmcollection.rb +455 -0
- data/lib/ovfparse/vmpackage.rb +22 -1
- data/lib/ovfparse.rb +1 -0
- metadata +5 -4
@@ -0,0 +1,455 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
class VmCollection
|
5
|
+
@url
|
6
|
+
@base_path
|
7
|
+
@name
|
8
|
+
@version
|
9
|
+
@protocol
|
10
|
+
@size
|
11
|
+
@xml
|
12
|
+
@package_details
|
13
|
+
@ovf_namespace
|
14
|
+
@default_namespace
|
15
|
+
|
16
|
+
|
17
|
+
attr_accessor :url, :base_path, :name, :version, :state, :protocol, :size, :xml, :references, :diskSection, :networkSection, :virtualSystemCollection, :package_details
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@package_details = Array.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
self.uri
|
25
|
+
end
|
26
|
+
|
27
|
+
def uri
|
28
|
+
if (nil==@protocol) then
|
29
|
+
return @url
|
30
|
+
else
|
31
|
+
return (@protocol + "://" + @url)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(uri)
|
36
|
+
@package_details = Array.new
|
37
|
+
if (URI::HTTP==uri.class) then
|
38
|
+
uri = uri.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
(@protocol, @url) = uri.split(":", 2) unless !uri
|
42
|
+
@url.sub!(/^\/{0,2}/, '')
|
43
|
+
@protocol.downcase
|
44
|
+
@url.downcase
|
45
|
+
@name = uri.split('/').last
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.create uri
|
49
|
+
(@protocol, @url) = uri.split(":", 2) unless !uri
|
50
|
+
@url.sub!(/^\/{0,2}/, '')
|
51
|
+
@protocol.downcase
|
52
|
+
@url.downcase
|
53
|
+
#if @protocol=='ftp'
|
54
|
+
# FtpVmPackage.new(uri)
|
55
|
+
if @protocol=='http'
|
56
|
+
HttpVmCollection.new(uri)
|
57
|
+
#elsif @protocol=='https'
|
58
|
+
# HttpsVmPackage.new(uri)
|
59
|
+
elsif @protocol=='file'
|
60
|
+
FileVmCollection.new(uri)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def fetch
|
66
|
+
end
|
67
|
+
|
68
|
+
# Caches all of the base elements inside Envelope for fast access
|
69
|
+
def loadElementRefs
|
70
|
+
children = @xml.root.children
|
71
|
+
@ovf_namespace = xml.root.namespace_definitions.detect{|ns| ns.prefix == "ovf"}
|
72
|
+
@default_namespace = xml.root.namespace
|
73
|
+
|
74
|
+
@references = getChildByName(xml.root, 'References')
|
75
|
+
@virtualSystemCollection = getChildByName(xml.root, 'VirtualSystemCollection')
|
76
|
+
|
77
|
+
@diskSection = getChildByName(xml.root, 'DiskSection') || @virtualSystem.add_previous_sibling(xml.create_element('DiskSection', {}))
|
78
|
+
@networkSection = getChildByName(xml.root, 'NetworkSection') || @virtualSystem.add_previous_sibling(xml.create_element('NetworkSection', {}))
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the first child node of the passed node whose name matches the passed name.
|
82
|
+
def getChildByName(node, childName)
|
83
|
+
return node.nil? ? nil : node.children.detect{ |element| element.name == childName}
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns every child node of the passed node whose name matches the passed name.
|
87
|
+
def getChildrenByName(node, childName)
|
88
|
+
return node.nil? ? [] : node.children.select{ |element| element.name == childName}
|
89
|
+
end
|
90
|
+
|
91
|
+
def checkschema(schema)
|
92
|
+
response = ""
|
93
|
+
|
94
|
+
isValid = true
|
95
|
+
schema.validate(@xml).each do |error|
|
96
|
+
response << error.message + "\n"
|
97
|
+
isValid = false
|
98
|
+
end
|
99
|
+
|
100
|
+
return [isValid, response]
|
101
|
+
end
|
102
|
+
|
103
|
+
def getVmName
|
104
|
+
return virtualSystem['id'] || ''
|
105
|
+
end
|
106
|
+
|
107
|
+
def getVmDescription
|
108
|
+
# ???
|
109
|
+
end
|
110
|
+
|
111
|
+
def getVmDisks
|
112
|
+
disks = Array.new
|
113
|
+
filenames = Hash.new
|
114
|
+
getChildrenByName(references, 'File').each { |node|
|
115
|
+
filenames[node['id']] = node['href']
|
116
|
+
}
|
117
|
+
|
118
|
+
getChildrenByName(diskSection, 'Disk').each { |node|
|
119
|
+
capacity = node['capacity']
|
120
|
+
units = node['capacityAllocationUnits']
|
121
|
+
if(units == "byte * 2^40")
|
122
|
+
capacity = (capacity.to_i * 1099511627776).to_s
|
123
|
+
elsif(units == "byte * 2^30")
|
124
|
+
capacity = (capacity.to_i * 1073741824).to_s
|
125
|
+
elsif(units == "byte * 2^20")
|
126
|
+
capacity = (capacity.to_i * 1048576).to_s
|
127
|
+
elsif(units == "byte * 2^10")
|
128
|
+
capacity = (capacity.to_i * 1024).to_s
|
129
|
+
end
|
130
|
+
thin_size = node['populatedSize']
|
131
|
+
disks.push({ 'name' => node['diskId'], 'location' => filenames[node['fileRef']], 'size' => capacity, 'thin_size' => (thin_size || "-1") })
|
132
|
+
}
|
133
|
+
|
134
|
+
return disks
|
135
|
+
end
|
136
|
+
|
137
|
+
def getVmNetworks
|
138
|
+
networks = Array.new
|
139
|
+
getChildrenByName(networkSection, 'Network').each { |node|
|
140
|
+
descriptionNode = getChildByName(node, 'Description')
|
141
|
+
text = descriptionNode.nil? ? '' : descriptionNode.text
|
142
|
+
networks.push({'location' => node['name'], 'notes' => text })
|
143
|
+
}
|
144
|
+
return networks
|
145
|
+
end
|
146
|
+
|
147
|
+
def getVirtualSystems
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.constructFromVmPackages(packages)
|
151
|
+
packages.each{ |package|
|
152
|
+
addVmPackage(package)
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
def addVmPackage(package)
|
157
|
+
details = PackageDetails.new()
|
158
|
+
details.id = package.getVmName
|
159
|
+
|
160
|
+
newRefs = package.getVmReferences
|
161
|
+
newRefs.each { |newRef|
|
162
|
+
addFileReference(newRef, package, details)
|
163
|
+
}
|
164
|
+
|
165
|
+
newDisks = package.getVmDisks
|
166
|
+
newDisks.each { |newDisk|
|
167
|
+
addDisk(newDisk, package, details)
|
168
|
+
}
|
169
|
+
|
170
|
+
newNetworks = package.getVmNetworks
|
171
|
+
newNetworks.each { |newNetwork|
|
172
|
+
addNetwork(newNetwork, package, details)
|
173
|
+
}
|
174
|
+
|
175
|
+
package_details.push(details)
|
176
|
+
addVirtualSystem(package.virtualSystem)
|
177
|
+
end
|
178
|
+
|
179
|
+
def addFileReference(pendingRef, childPackage, details)
|
180
|
+
# Compare this one to all the existing ones to prevent duplicates
|
181
|
+
isNewRef = true
|
182
|
+
currentFileRefs = getChildrenByName(references, 'File')
|
183
|
+
currentFileRefs.each{ |oldRef|
|
184
|
+
if(compareFileReferences(oldRef, pendingRef))
|
185
|
+
isNewRef = false
|
186
|
+
break
|
187
|
+
end
|
188
|
+
}
|
189
|
+
|
190
|
+
# If it's not a dup, add it
|
191
|
+
if(isNewRef)
|
192
|
+
newFileID = "file" + (currentFileRefs.length + 1).to_s
|
193
|
+
newFile = references.add_child(xml.create_element('File', {'href' => pendingRef['href'], 'id' => newFileID, 'size' => pendingRef['size']}))
|
194
|
+
newFile.attribute("href").namespace = @ovf_namespace
|
195
|
+
newFile.attribute("id").namespace = @ovf_namespace
|
196
|
+
newFile.attribute("size").namespace = @ovf_namespace
|
197
|
+
findReplace(childPackage, pendingRef['id'], newFileID)
|
198
|
+
details.files.push(newFileID)
|
199
|
+
else
|
200
|
+
details.files.push(pendingRef['href'])
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def compareFileReferences(oldRef, newRef)
|
205
|
+
return (oldRef['href'] == newRef['href']) #&& (oldRef['size'] == newRef['size'])
|
206
|
+
end
|
207
|
+
|
208
|
+
def addDisk(newDisk, childPackage, details)
|
209
|
+
# Always add a disk, even if it's a clone, cause this VM will need its own copy
|
210
|
+
isNewDisk = true
|
211
|
+
currentDisks = getChildrenByName(diskSection, 'Disk')
|
212
|
+
#currentDisks.each{ |oldDisk|
|
213
|
+
# if(compareDisks(oldDisk, newDisk))
|
214
|
+
# isNewDisk = false
|
215
|
+
# break
|
216
|
+
# end
|
217
|
+
#}
|
218
|
+
|
219
|
+
if(isNewDisk)
|
220
|
+
newDiskID = "vmdisk" + (currentDisks.length + 1).to_s
|
221
|
+
newDiskNode = diskSection.add_child(xml.create_element('Disk', {
|
222
|
+
'capacity' => newDisk['size'],
|
223
|
+
'diskId' => newDiskID,
|
224
|
+
'fileRef' => getChildrenByName(references, 'File').detect{ |ref| ref['href'] == newDisk['location'] }['id'],
|
225
|
+
'format' => "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized",
|
226
|
+
'populatedSize' => newDisk['thin_size']
|
227
|
+
}))
|
228
|
+
newDiskNode.attribute("capacity").namespace = @ovf_namespace
|
229
|
+
newDiskNode.attribute("diskId").namespace = @ovf_namespace
|
230
|
+
newDiskNode.attribute("fileRef").namespace = @ovf_namespace
|
231
|
+
newDiskNode.attribute("format").namespace = @ovf_namespace
|
232
|
+
newDiskNode.attribute("populatedSize").namespace = @ovf_namespace
|
233
|
+
findReplace(childPackage, newDisk['name'], newDiskID)
|
234
|
+
details.disks.push(newDiskID)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def compareDisks(oldDisk, newDisk)
|
239
|
+
filename = getChildrenByName(references, 'File').detect{ |ref| ref['id'] == oldDisk['fileRef'] }['href']
|
240
|
+
return (filename == newDisk['location'])
|
241
|
+
end
|
242
|
+
|
243
|
+
def addNetwork(newNetwork, childPackage, details)
|
244
|
+
isNewNetwork = true
|
245
|
+
currentNetworks = getChildrenByName(networkSection, 'Network')
|
246
|
+
currentNetworks.each{ |oldNetwork|
|
247
|
+
if(compareNetworks(oldNetwork, newNetwork))
|
248
|
+
isNewNetwork = false
|
249
|
+
break
|
250
|
+
end
|
251
|
+
}
|
252
|
+
|
253
|
+
if(isNewNetwork)
|
254
|
+
newNode = networkSection.add_child(xml.create_element('Network', {'name' => newNetwork['location']}))
|
255
|
+
newNode.attribute("name").namespace = @ovf_namespace
|
256
|
+
newNode.add_child(xml.create_element('Description', newNetwork['notes']))
|
257
|
+
end
|
258
|
+
details.networks.push(newNetwork['location'])
|
259
|
+
end
|
260
|
+
|
261
|
+
def compareNetworks(oldNetwork, newNetwork)
|
262
|
+
return (oldNetwork['name'] == newNetwork['location'])
|
263
|
+
end
|
264
|
+
|
265
|
+
def addVirtualSystem(newSystem)
|
266
|
+
ovfNamespace = xml.root.namespace
|
267
|
+
newNode = virtualSystemCollection.add_child(newSystem.clone)
|
268
|
+
newNode.namespace = ovfNamespace
|
269
|
+
end
|
270
|
+
|
271
|
+
def findReplace(package, oldval, newval)
|
272
|
+
package.xml.xpath("//*").each{ |node|
|
273
|
+
if(node.children.length == 1 && node.children[0].text? && node.content.match(oldval) != nil)
|
274
|
+
node.content = node.content.gsub(oldval, newval)
|
275
|
+
end
|
276
|
+
node.attributes.each{ |key, attr|
|
277
|
+
attr.value = attr.value.gsub(oldval, newval)
|
278
|
+
}
|
279
|
+
}
|
280
|
+
end
|
281
|
+
|
282
|
+
def search(virtualSystem, value)
|
283
|
+
virtualSystem.xpath(".//*").each{ |node|
|
284
|
+
if(node.children.length == 1 && node.children[0].text? && node.content.match(value) != nil)
|
285
|
+
return true
|
286
|
+
end
|
287
|
+
node.attributes.each{ |key, attr|
|
288
|
+
if(attr.value.match(value) != nil)
|
289
|
+
return true
|
290
|
+
end
|
291
|
+
}
|
292
|
+
}
|
293
|
+
return false
|
294
|
+
end
|
295
|
+
|
296
|
+
# @todo any need to make this a general purpose "writer" ?
|
297
|
+
def self.constructSkeleton
|
298
|
+
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
299
|
+
xml.Envelope('xmlns' => 'http://schemas.dmtf.org/ovf/envelope/1', 'xmlns:cim' => "http://schemas.dmtf.org/wbem/wscim/1/common", 'xmlns:ovf' => "http://schemas.dmtf.org/ovf/envelope/1", 'xmlns:rasd' => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData", 'xmlns:vmw' => "http://www.vmware.com/schema/ovf", 'xmlns:vssd' => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData", 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", 'xmlns:cops' => 'http://cops.mitre.org/1.2', 'xmlns:cpe' => 'http://cpe.mitre.org/dictionary/2.0') {
|
300
|
+
xml.References{}
|
301
|
+
xml.DiskSection{
|
302
|
+
xml.Info "Virtual disk information"
|
303
|
+
}
|
304
|
+
xml.NetworkSection{
|
305
|
+
xml.Info "List of logical networks"
|
306
|
+
}
|
307
|
+
xml.VirtualSystemCollection('ovf:id' => "vm_collection"){
|
308
|
+
xml.Info "A collection of virtual machines"
|
309
|
+
}
|
310
|
+
}
|
311
|
+
|
312
|
+
node = Nokogiri::XML::Comment.new(xml.doc, ' skeleton framework constructed by OVFparse ')
|
313
|
+
xml.doc.children[0].add_previous_sibling(node)
|
314
|
+
end
|
315
|
+
|
316
|
+
newPackage = NewVmCollection.new
|
317
|
+
newPackage.xml = builder.doc
|
318
|
+
newPackage.loadElementRefs
|
319
|
+
return newPackage
|
320
|
+
end
|
321
|
+
|
322
|
+
def writeXML(filename)
|
323
|
+
file = File.new(filename, "w")
|
324
|
+
file.puts(xml.to_s)
|
325
|
+
file.close
|
326
|
+
end
|
327
|
+
|
328
|
+
def splitIntoPackages
|
329
|
+
packages = Array.new
|
330
|
+
|
331
|
+
i = 0
|
332
|
+
virtualSystems = getChildrenByName(virtualSystemCollection, "VirtualSystem")
|
333
|
+
virtualSystems.each{ |virtualSystem|
|
334
|
+
details = package_details[i]
|
335
|
+
new_package = VmPackage.construct_skeleton
|
336
|
+
new_package.loadElementRefs
|
337
|
+
|
338
|
+
details.files.each{ |file|
|
339
|
+
node = getChildrenByName(references, "File").detect{ |node| node['id'] == file }
|
340
|
+
new_package.references.add_child(node.clone)
|
341
|
+
}
|
342
|
+
|
343
|
+
details.disks.each{ |disk|
|
344
|
+
node = getChildrenByName(diskSection, "Disk").detect{ |node| node['diskId'] == disk }
|
345
|
+
new_package.diskSection.add_child(node.clone)
|
346
|
+
}
|
347
|
+
|
348
|
+
details.networks.each{ |network|
|
349
|
+
node = getChildrenByName(networkSection, "Network").detect{ |node| node['name'] == network }
|
350
|
+
new_package.networkSection.add_child(node.clone)
|
351
|
+
}
|
352
|
+
|
353
|
+
new_package.virtualSystem.children.unlink
|
354
|
+
new_package.virtualSystem.add_child(virtualSystem.clone.children)
|
355
|
+
new_package.virtualSystem.children.each{ |child|
|
356
|
+
child.namespace = new_package.virtualSystem.namespace
|
357
|
+
}
|
358
|
+
packages.push(new_package)
|
359
|
+
|
360
|
+
i += 1
|
361
|
+
}
|
362
|
+
|
363
|
+
return packages
|
364
|
+
end
|
365
|
+
|
366
|
+
def parseXML
|
367
|
+
fileRefs = Hash.new
|
368
|
+
fileNames = Array.new
|
369
|
+
getChildrenByName(references, "File").each{ |fileRef|
|
370
|
+
fileNames.push(fileRef['id'])
|
371
|
+
}
|
372
|
+
|
373
|
+
diskNames = Array.new
|
374
|
+
getChildrenByName(diskSection, "Disk").each{ |disk|
|
375
|
+
diskNames.push(disk['diskId'])
|
376
|
+
fileRefs[disk['diskId']] = disk['fileRef']
|
377
|
+
}
|
378
|
+
|
379
|
+
networkNames = Array.new
|
380
|
+
getChildrenByName(networkSection, "Network").each{ |network|
|
381
|
+
networkNames.push(network['name'])
|
382
|
+
}
|
383
|
+
|
384
|
+
getChildrenByName(virtualSystemCollection, "VirtualSystem").each{ |virtualSystem|
|
385
|
+
details = PackageDetails.new()
|
386
|
+
details.id = virtualSystem['id']
|
387
|
+
|
388
|
+
fileNames.each{ |fileName|
|
389
|
+
if(search(virtualSystem, fileName))
|
390
|
+
details.files.push(fileName)
|
391
|
+
end
|
392
|
+
}
|
393
|
+
|
394
|
+
diskNames.each{ |diskName|
|
395
|
+
if(search(virtualSystem, diskName))
|
396
|
+
details.disks.push(diskName)
|
397
|
+
if(!details.files.include?(fileRefs[diskName]))
|
398
|
+
details.files.push(fileRefs[diskName])
|
399
|
+
end
|
400
|
+
end
|
401
|
+
}
|
402
|
+
|
403
|
+
networkNames.each{ |networkName|
|
404
|
+
if(search(virtualSystem, networkName))
|
405
|
+
details.networks.push(networkName)
|
406
|
+
end
|
407
|
+
}
|
408
|
+
|
409
|
+
package_details.push(details)
|
410
|
+
}
|
411
|
+
end
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
class NewVmCollection < VmCollection
|
416
|
+
def initialize
|
417
|
+
@package_details = Array.new
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
class HttpVmCollection < VmCollection
|
422
|
+
def fetch
|
423
|
+
url = URI.parse(URI.escape(self.uri))
|
424
|
+
@xml = Nokogiri::XML(open(url)) do |config|
|
425
|
+
config.noblanks.strict.noent
|
426
|
+
end
|
427
|
+
|
428
|
+
loadElementRefs
|
429
|
+
parseXML
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
class FileVmCollection < VmCollection
|
434
|
+
def fetch
|
435
|
+
@xml = Nokogiri::XML(File.open(self.url)) do |config|
|
436
|
+
config.noblanks.strict.noent
|
437
|
+
end
|
438
|
+
|
439
|
+
loadElementRefs
|
440
|
+
parseXML
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
class PackageDetails
|
445
|
+
|
446
|
+
attr_accessor :id, :files, :disks, :networks
|
447
|
+
|
448
|
+
def initialize
|
449
|
+
@id = ""
|
450
|
+
@files = Array.new
|
451
|
+
@disks = Array.new
|
452
|
+
@networks = Array.new
|
453
|
+
end
|
454
|
+
|
455
|
+
end
|
data/lib/ovfparse/vmpackage.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'nokogiri'
|
1
2
|
require 'open-uri'
|
2
3
|
|
3
4
|
class VmPackage
|
@@ -237,7 +238,9 @@ class VmPackage
|
|
237
238
|
getChildrenByName(diskSection, 'Disk').each { |node|
|
238
239
|
capacity = node['capacity']
|
239
240
|
units = node['capacityAllocationUnits']
|
240
|
-
if(units == "byte * 2^
|
241
|
+
if(units == "byte * 2^40")
|
242
|
+
capacity = (capacity.to_i * 1099511627776).to_s
|
243
|
+
elsif(units == "byte * 2^30")
|
241
244
|
capacity = (capacity.to_i * 1073741824).to_s
|
242
245
|
elsif(units == "byte * 2^20")
|
243
246
|
capacity = (capacity.to_i * 1048576).to_s
|
@@ -261,6 +264,13 @@ class VmPackage
|
|
261
264
|
return networks
|
262
265
|
end
|
263
266
|
|
267
|
+
def getVmReferences
|
268
|
+
refs = Array.new
|
269
|
+
getChildrenByName(references, 'File').each { |node|
|
270
|
+
refs.push({'href' => node['href'], 'id' => node['id'], 'size' => node['size']})
|
271
|
+
}
|
272
|
+
return refs
|
273
|
+
end
|
264
274
|
|
265
275
|
def getVmCPUs
|
266
276
|
return getVirtualQuantity(3)
|
@@ -565,6 +575,17 @@ class VmPackage
|
|
565
575
|
end
|
566
576
|
end
|
567
577
|
|
578
|
+
def setPropertyDefault(key, newVal)
|
579
|
+
getChildrenByName(virtualSystem, "ProductSection").each{ |product|
|
580
|
+
getChildrenByName(product, "Property").each{ |property|
|
581
|
+
if(property['key'] == key)
|
582
|
+
property['ovf:value'] = newVal
|
583
|
+
return
|
584
|
+
end
|
585
|
+
}
|
586
|
+
}
|
587
|
+
end
|
588
|
+
|
568
589
|
def setElements(updated_element, parent_node, element_list)
|
569
590
|
element_list.each { |element_details|
|
570
591
|
updated_value = updated_element[element_details['element_ref']]
|
data/lib/ovfparse.rb
CHANGED
@@ -8,6 +8,7 @@ path = File.expand_path(File.dirname(__FILE__))
|
|
8
8
|
|
9
9
|
require path + '/ovfparse/vmrepository'
|
10
10
|
require path + '/ovfparse/vmpackage'
|
11
|
+
require path + '/ovfparse/vmcollection'
|
11
12
|
require path + '/ovfparse/os_id_table'
|
12
13
|
require path + '/ovfparse/esx4_vmrepository'
|
13
14
|
require path + '/ovfparse/file_vmrepository'
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ovfparse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 57
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 1
|
10
|
+
version: 0.9.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jim Barkley
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-10-10 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/ovfparse/marketplace_repository.rb
|
49
49
|
- lib/ovfparse/vc_repository.rb
|
50
50
|
- lib/ovfparse/https_vmrepository.rb
|
51
|
+
- lib/ovfparse/vmcollection.rb
|
51
52
|
- lib/ovfparse/vmrepository.rb
|
52
53
|
- lib/ovfparse/esx_repository.rb
|
53
54
|
- lib/ovfparse/vmpackage.rb
|