ovfparse 0.0.7 → 0.0.81

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README +3 -2
  2. data/lib/ovfparse/vmpackage.rb +531 -2
  3. metadata +12 -5
data/README CHANGED
@@ -19,8 +19,9 @@ From inside your ovfparse directory:
19
19
  $ rake gem
20
20
  $ cd pkg
21
21
  $ gem install ovfparse[-version]
22
-
23
- [Coming soon: gem install ovfparse (from rubygems.org)]
22
+
23
+ Or from RubyGems:
24
+ $ gem install ovfparse
24
25
 
25
26
  === Example1
26
27
  ------------
@@ -20,6 +20,32 @@ class VmPackage
20
20
  COPYING = 4
21
21
  BOOTING = 5
22
22
  CONFIGURING = 6
23
+
24
+ # List of attributes in an OVF product that we will extract / set
25
+ PRODUCT_ATTRIBUTES = [ {'full_name' => 'ovf:instance', 'node_ref' => 'instance', 'attribute_ref' => 'instance'},
26
+ {'full_name' => 'ovf:class', 'node_ref' => 'class', 'attribute_ref' => 'product_class'} ]
27
+
28
+ # List of elements in an OVF product that we will extract / set
29
+ PRODUCT_ELEMENTS = [ {'full_name' => 'ovf:Info', 'node_ref' => 'Info', 'element_ref' => 'description', 'required' => false},
30
+ {'full_name' => 'ovf:Product', 'node_ref' => 'Product', 'element_ref' => 'name', 'required' => false},
31
+ {'full_name' => 'ovf:Vendor', 'node_ref' => 'Vendor', 'element_ref' => 'vendor', 'required' => false},
32
+ {'full_name' => 'ovf:Version', 'node_ref' => 'Version', 'element_ref' => 'version', 'required' => false} ]
33
+
34
+ # List of attributes in an OVF property that we will extract / set
35
+ PROPERTY_ATTRIBUTES = [ {'full_name' => 'ovf:value', 'node_ref' => 'value', 'attribute_ref' => 'value'},
36
+ {'full_name' => 'ovf:key', 'node_ref' => 'key', 'attribute_ref' => 'key'},
37
+ {'full_name' => 'ovf:userConfigurable', 'node_ref' => 'userConfigurable', 'attribute_ref' => 'userConfigurable'},
38
+ {'full_name' => 'ovf:password', 'node_ref' => 'password', 'attribute_ref' => 'password'},
39
+ {'full_name' => 'ovf:required', 'node_ref' => 'required', 'attribute_ref' => 'required'},
40
+ {'full_name' => 'ovf:type', 'node_ref' => 'type', 'attribute_ref' => 'value_basetype'},
41
+ {'full_name' => 'cops:valueType', 'node_ref' => 'valueType', 'attribute_ref' => 'valueType'},
42
+ {'full_name' => 'cops:uuid', 'node_ref' => 'uuid', 'attribute_ref' => 'uuid'} ]
43
+
44
+ # List of elements in an OVF property that we will extract / set
45
+ PROPERTY_ELEMENTS = [ {'full_name' => 'ovf:Label', 'node_ref' => 'Label', 'element_ref' => 'name', 'required' => false},
46
+ {'full_name' => 'ovf:Description', 'node_ref' => 'Description', 'element_ref' => 'description', 'required' => false},
47
+ {'full_name' => 'cops:Example', 'node_ref' => 'cops:Example', 'element_ref' => 'example', 'required' => true},
48
+ {'full_name' => 'cops:NoneType', 'node_ref' => 'cops:NoneType', 'element_ref' => 'nonetype', 'required' => true} ]
23
49
 
24
50
  OVF_NAMESPACE = {'ovf' => 'http://schemas.dmtf.org/ovf/envelope/1'}
25
51
 
@@ -120,6 +146,510 @@ class VmPackage
120
146
 
121
147
  end
122
148
 
149
+ def checkschema(schema)
150
+ xsd = Nokogiri::XML::Schema(File.read(schema))
151
+ response = ""
152
+
153
+ isValid = true
154
+ xsd.validate(@xml).each do |error|
155
+ response << error.message + "\n"
156
+ isValid = false
157
+ end
158
+
159
+ return [isValid, response]
160
+ end
161
+
162
+ def getVmName
163
+ return xml.xpath('ovf:Envelope/ovf:VirtualSystem')[0]['id']
164
+ end
165
+
166
+ def getVmDescription
167
+ descNode = xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:Info')[0]
168
+ return descNode.nil? ? '' : descNode.content
169
+ end
170
+
171
+ def getVmOS_ID
172
+ return xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection')[0]['id']
173
+ end
174
+
175
+ def getVmPatchLevel
176
+ patchNode = xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection/ovf:Description')[0]
177
+ return patchNode.nil? ? '' : patchNode.text
178
+ end
179
+
180
+ def getVmAttributes
181
+ return {
182
+ 'name' => getVmName,
183
+ 'description' => getVmDescription,
184
+ 'OS' => getVmOS_ID,
185
+ 'patch_level' => getVmPatchLevel,
186
+ 'CPUs' => getVmCPUs,
187
+ 'RAM' => getVmRAM
188
+ }
189
+ end
190
+
191
+ def getVmDisks
192
+ disks = Array.new
193
+ filenames = Hash.new
194
+ xml.xpath('ovf:Envelope/ovf:References/ovf:File').each { |node|
195
+ filenames[node['id']] = node['href']
196
+ }
197
+
198
+ xml.xpath('ovf:Envelope/ovf:DiskSection/ovf:Disk').each { |node|
199
+ disks.push({ 'name' => node['diskId'], 'location' => filenames[node['fileRef']], 'size' => node['capacity'] })
200
+ }
201
+
202
+ return disks
203
+ end
204
+
205
+ def getVmNetworks
206
+ networks = Array.new
207
+ xml.xpath('ovf:Envelope/ovf:NetworkSection/ovf:Network').each { |node|
208
+ descriptionNode = node.xpath('ovf:Description')[0]
209
+ text = descriptionNode.nil? ? '' : descriptionNode.text
210
+ networks.push({'location' => node['name'], 'notes' => text })
211
+ }
212
+ return networks
213
+ end
214
+
215
+ # What a long strange trip it's been.
216
+ def getVmProducts
217
+ products = Array.new
218
+ xml.root.add_namespace('cops', 'http://cops.mitre.org/1.1')
219
+ xml.root.add_namespace('cpe', 'http://cpe.mitre.org/dictionary/2.0')
220
+
221
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:ProductSection').each { |productNode|
222
+ product = Hash.new
223
+
224
+ PRODUCT_ATTRIBUTES.each { |attribute_details|
225
+ product[attribute_details['attribute_ref']] = productNode[attribute_details['node_ref']]
226
+ }
227
+
228
+ PRODUCT_ELEMENTS.each { |element_details|
229
+ childNode = productNode.xpath(element_details['full_name'])[0]
230
+ product[element_details['element_ref']] = childNode.nil? ? '' : childNode.content
231
+ }
232
+
233
+ childNode = productNode.xpath('ovf:Icon')[0]
234
+ begin
235
+ product['icon'] = childNode.nil? ? '' :
236
+ (xml.xpath('ovf:Envelope/ovf:References/ovf:File').detect { |file| file['id'] == childNode['fileRef'] })['href']
237
+ rescue
238
+ puts "You have an icon reference to a file that doesn't exist in the References section."
239
+ return ''
240
+ end
241
+
242
+ properties = Array.new
243
+ productNode.xpath('ovf:Property').each { |propertyNode|
244
+ property = Hash.new
245
+ PROPERTY_ATTRIBUTES.each { |attribute_details|
246
+ property[attribute_details['attribute_ref']] = propertyNode[attribute_details['node_ref']]
247
+ }
248
+
249
+ PROPERTY_ELEMENTS.each { |element_details|
250
+ childNode = propertyNode.xpath(element_details['full_name'])[0]
251
+ property[element_details['element_ref']] = childNode.nil? ? '' : childNode.content
252
+ }
253
+
254
+ valueOptionsArray = Array.new
255
+
256
+ node = propertyNode.xpath('cops:ValueOptions')[0]
257
+ if(!node.nil?)
258
+ if (!node['selection'].nil?)
259
+ property['selection'] = node['selection']
260
+ end
261
+ node.xpath('cops:Option').each { |valueOption|
262
+ valueOptionsArray.push(valueOption.content)
263
+ }
264
+ end
265
+
266
+ default = propertyNode['value']
267
+ existingDefault = valueOptionsArray.detect { |option| option == default }
268
+ if (!default.nil? && default != '' && existingDefault.nil?)
269
+ valueOptionsArray.insert(0, default)
270
+ end
271
+
272
+ property['valueoptions'] = valueOptionsArray.join("\n")
273
+
274
+ actions = Array.new
275
+ node = propertyNode.xpath('cops:Action')[0]
276
+ if(!node.nil?)
277
+ node.xpath('cops:FindReplace').each { |findReplace|
278
+ actions.push({'action_type' => 'FindReplace', 'path' => findReplace.xpath('cops:Path')[0].content, 'value' => findReplace.xpath('cops:Token')[0].content})
279
+ }
280
+ node.xpath('cops:Insert').each { |insert|
281
+ lineNumberNode = insert.xpath('cops:LineNumber')[0]
282
+ lineNumber = lineNumberNode.nil? ? '' : lineNumberNode.content
283
+ actions.push({'action_type' => 'Insert', 'path' => insert.xpath('cops:Path')[0].content, 'value' => lineNumber})
284
+ }
285
+ node.xpath('cops:Registry').each { |registry|
286
+ actions.push({'action_type' => 'Registry', 'path' => registry.xpath('cops:RegistryPath')[0].content, 'value' => ''})
287
+ }
288
+ node.xpath('cops:Execute').each { |execute|
289
+ optionsNode = execute.xpath('cops:Options')[0]
290
+ options = optionsNode.nil? ? '' : optionsNode.content
291
+ actions.push({'action_type' => 'Execute', 'path' => execute.xpath('cops:Path')[0].content, 'value' => options})
292
+ }
293
+
294
+ end
295
+
296
+ container = [property, actions]
297
+ properties.push(container)
298
+ }
299
+
300
+ container = [product, properties]
301
+ products.push(container)
302
+ }
303
+ return products
304
+ end
305
+
306
+ def getVmCPUs
307
+ return getVirtualQuantity(3)
308
+ end
309
+
310
+ def getVmRAM
311
+ return getVirtualQuantity(4)
312
+ end
313
+
314
+ def getVirtualQuantity(resource)
315
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item').each { |node|
316
+ resourceType = node.xpath('rasd:ResourceType')[0].text
317
+ resourceType == resource.to_s ? (return node.xpath('rasd:VirtualQuantity')[0].text) : next
318
+ }
319
+ end
320
+
321
+ def setVmName(newValue)
322
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem')[0]['ovf:id'] = newValue
323
+ nameNode = xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:Name')[0] ||
324
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:Info')[0].add_next_sibling(xml.create_element('Name', {}))
325
+ nameNode.content = newValue
326
+ end
327
+
328
+ def setVmDescription(newValue)
329
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:Info')[0].content = newValue
330
+ end
331
+
332
+ def setVmOS_ID(newValue)
333
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection')[0]['ovf:id'] = newValue.to_s
334
+ end
335
+
336
+ def setVmPatchLevel(newValue)
337
+ osNode = xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:OperatingSystemSection')[0]
338
+ descNode = osNode.xpath('ovf:Description')[0] || osNode.add_child(xml.create_element('Description', {}))
339
+ descNode.content = newValue
340
+ end
341
+
342
+ def setVmCPUs(newValue)
343
+ setVirtualQuantity(3, newValue)
344
+ end
345
+
346
+ def setVmRAM(newValue)
347
+ setVirtualQuantity(4, newValue)
348
+ end
349
+
350
+ def setVirtualQuantity(resource, newValue)
351
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item').each { |node|
352
+ resourceType = node.xpath('rasd:ResourceType')[0].text
353
+ resourceType == resource.to_s ? (node.xpath('rasd:VirtualQuantity')[0].content = newValue) : next
354
+ }
355
+ end
356
+
357
+ def setVmNetworks(networks)
358
+ networkSection = xml.xpath('ovf:Envelope/ovf:NetworkSection')[0]
359
+ networkNodes = networkSection.xpath('ovf:Network')
360
+
361
+ networkNodes.each { |node|
362
+ updated_network = networks.detect { |network| network.location == node['name'] }
363
+ if(updated_network.nil?)
364
+ node.unlink
365
+ else
366
+ descriptionNode = node.xpath('ovf:Description')[0]
367
+ if((updated_network.notes == '' || updated_network.notes.nil?) && !descriptionNode.nil?)
368
+ descriptionNode.unlink
369
+ elsif(updated_network.notes != '' && !updated_network.notes.nil?)
370
+ descriptionNode = descriptionNode || descriptionNode.add_child(xml.create_element("Description", {}))
371
+ descriptionNode.content = updated_network.notes
372
+ end
373
+ end
374
+ }
375
+
376
+ networks.each { |network|
377
+ if( (networkNodes.detect { |node| network.location == node['name'] }).nil?)
378
+ networkNode = networkSection.add_child(xml.create_element('Network', {'ovf:name' => network.location}))
379
+ if(network.notes != '' && !network.notes.nil?)
380
+ networkNode.add_child(xml.create_element('Description', network.notes))
381
+ end
382
+ end
383
+ }
384
+ end
385
+
386
+ def setVmDisks(disks)
387
+ fileSection = xml.xpath('ovf:Envelope/ovf:References')[0]
388
+ fileNodes = fileSection.xpath('ovf:File')
389
+
390
+ diskSection = xml.xpath('ovf:Envelope/ovf:DiskSection')[0]
391
+ diskNodes = diskSection.xpath('ovf:Disk')
392
+
393
+ icons = Array.new
394
+ xml.xpath('ovf:Envelope/ovf:VirtualSystem/ovf:ProductSection/ovf:Icon').each { |node|
395
+ icons.push(node['fileRef'])
396
+ }
397
+
398
+ fileNodes.each { |file_node|
399
+ updated_disk = disks.detect { |disk| disk.location == file_node['href'] }
400
+ old_disk_node = diskNodes.detect { |old_node| old_node['id'] == file_node['fileRef'] }
401
+
402
+ if(updated_disk.nil?)
403
+ if((icons.detect { |fileRef| fileRef == file_node['id'] }).nil?)
404
+ file_node.unlink
405
+ if(!old_disk_node.nil?)
406
+ old_disk_node.unlink
407
+ end
408
+ end
409
+ else
410
+ file_node['ovf:id'] = updated_disk.name + '_disk'
411
+ old_disk_node['ovf:fileRef'] = updated_disk.name + '_disk'
412
+ old_disk_node['ovf:capacity'] = updated_disk.size.to_s
413
+ old_disk_node['ovf:diskId'] = updated_disk.name
414
+ end
415
+ }
416
+
417
+ disks.each { |disk|
418
+ if( (fileNodes.detect { |node| disk.location == node['href'] }).nil?)
419
+ diskSection.add_child(xml.create_element('Disk', {'ovf:capacity' => disk.size.to_s, 'ovf:capacityAllocationUnits' => "byte * 2^30", 'ovf:diskId' => disk.name, 'ovf:fileRef' => disk.name + '_disk', 'ovf:format' => "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" }))
420
+ fileSection.add_child(xml.create_element('File', {'ovf:href' => disk.location, 'ovf:id' => disk.name + '_disk'}))
421
+ end
422
+ }
423
+ end
424
+
425
+ def setVmAttributes(attributes)
426
+ if attributes['name']
427
+ setVmName(attributes['name'])
428
+ end
429
+ if attributes['description']
430
+ setVmDescription(attributes['description'])
431
+ end
432
+ if attributes['OS']
433
+ setVmOS_ID(attributes['OS'])
434
+ end
435
+ if attributes['patch_level']
436
+ setVmPatchLevel(attributes['patch_level'])
437
+ end
438
+ if attributes['CPUs']
439
+ setVmCPUs(attributes['CPUs'])
440
+ end
441
+ if attributes['RAM']
442
+ setVmRAM(attributes['RAM'])
443
+ end
444
+ end
445
+
446
+ def setProductIcon(new_icon, productNode)
447
+ iconNode = productNode.xpath('ovf:Icon')[0]
448
+ if((new_icon == '' || new_icon.nil?) && !iconNode.nil?)
449
+ (xml.xpath('ovf:Envelope/ovf:References/ovf:File').detect { |fileNode| fileNode['id'] == iconNode['fileRef']}).unlink
450
+ iconNode.unlink
451
+ elsif(new_icon != '' && !new_icon.nil?)
452
+ if(iconNode.nil?)
453
+ productNode.add_child(xml.create_element('Icon', {'ovf:fileRef' => productNode['class'] + '_icon'}))
454
+ xml.xpath('ovf:Envelope/ovf:References')[0].add_child(xml.create_element('File', {'ovf:id' => productNode['class'] + '_icon', 'ovf:href' => new_icon}))
455
+ else
456
+ (xml.xpath('ovf:Envelope/ovf:References/ovf:File').detect { |fileNode| fileNode['id'] == iconNode['fileRef']})['ovf:href'] = new_icon
457
+ end
458
+ end
459
+ end
460
+
461
+ def setElements(updated_element, parent_node, element_list)
462
+ element_list.each { |element_details|
463
+ updated_value = updated_element[element_details['element_ref']]
464
+ element_node = parent_node.xpath(element_details['full_name'])[0]
465
+ if((updated_value == '' || updated_value.nil?) && !element_node.nil?)
466
+ element_node.unlink
467
+ elsif(updated_value != '' && !updated_value.nil?)
468
+ element_node = element_node || parent_node.add_child(xml.create_element(element_details['node_ref'], updated_value))
469
+ element_node.content = updated_value
470
+ if(element_details['required'])
471
+ element_node['ovf:required'] = 'false'
472
+ end
473
+ end
474
+ }
475
+ end
476
+
477
+ def setAttributes(updated_element, parent_node, attribute_list)
478
+ attribute_list.each { |attribute_details|
479
+ updated_value = updated_element[attribute_details['attribute_ref']]
480
+ (updated_value == '' || updated_value.nil?) ? parent_node.delete(attribute_details['node_ref']) : parent_node[attribute_details['full_name']] = updated_value
481
+ }
482
+ end
483
+
484
+ def setVmProducts(products)
485
+ virtualSystem = xml.xpath('ovf:Envelope/ovf:VirtualSystem')[0]
486
+ productNodes = virtualSystem.xpath('ovf:ProductSection')
487
+
488
+ # Removing old ones that don't exist anymore, updating ones that do
489
+ productNodes.each { |productNode|
490
+ updated_product = products.detect { |product| productNode['class'] == product.product_class }
491
+ if(updated_product.nil?)
492
+ productNode.unlink
493
+ else
494
+ setAttributes(updated_product, productNode, PRODUCT_ATTRIBUTES)
495
+ setElements(updated_product, productNode, PRODUCT_ELEMENTS)
496
+ setProductIcon(updated_product.icon, productNode)
497
+ setProperties(productNode, updated_product.coat_properties)
498
+ end
499
+ }
500
+
501
+ # Adding new products
502
+ products.each { |product|
503
+ if((productNodes.detect { |node| node['class'] == product.product_class }).nil?)
504
+ newProductNode = virtualSystem.add_child(xml.create_element('ProductSection', {}))
505
+ setAttributes(product, newProductNode, PRODUCT_ATTRIBUTES)
506
+ setElements(product, newProductNode, PRODUCT_ELEMENTS)
507
+ setProductIcon(product.icon, newProductNode)
508
+ setProperties(newProductNode, product.coat_properties)
509
+ end
510
+ }
511
+ end
512
+
513
+ def setProperties(product, properties)
514
+ propertyNodes = product.xpath('ovf:Property')
515
+
516
+ propertyNodes.each { |propertyNode|
517
+ updated_property = properties.detect { |property| propertyNode['key'] == property.key }
518
+ if(updated_property.nil?)
519
+ propertyNode.unlink
520
+ else
521
+ setAttributes(updated_property, propertyNode, PROPERTY_ATTRIBUTES)
522
+ setElements(updated_property, propertyNode, PROPERTY_ELEMENTS)
523
+ setValueOptions(propertyNode, updated_property)
524
+ propertyNode['ovf:type'] = 'string'
525
+ setActions(propertyNode, updated_property.coat_actions)
526
+ end
527
+ }
528
+
529
+ properties.each { |property|
530
+ if((propertyNodes.detect { |node| node['key'] == property.key }).nil?)
531
+ newPropertyNode = product.add_child(xml.create_element('Property', {}))
532
+ setAttributes(property, newPropertyNode, PROPERTY_ATTRIBUTES)
533
+ setElements(property, newPropertyNode, PROPERTY_ELEMENTS)
534
+ setValueOptions(newPropertyNode, property)
535
+ newPropertyNode['ovf:type'] = 'string'
536
+ setActions(newPropertyNode, property.coat_actions)
537
+ end
538
+ }
539
+ end
540
+
541
+ def setValueOptions(property_node, property)
542
+ values = property.valueoptions.split("\n")
543
+ valueOptionsNode = property_node.xpath('cops:ValueOptions')[0]
544
+ if(values.empty? && !valueOptionsNode.nil?)
545
+ valueOptionsNode.unlink
546
+ elsif(!values.empty?)
547
+ valueOptionsNode = valueOptionsNode || property_node.add_child(xml.create_element('ValueOptions', {}))
548
+ valueOptionsNode.namespace = xml.root.namespace_definitions.detect{ |ns| ns.prefix == 'cops' }
549
+ valueOptionsNode['cops:selection'] = (property.selection || 'single')
550
+ valueOptionsNode['ovf:required'] = 'false'
551
+ valueOptionsNode.children.unlink
552
+ existingDefault = values.detect { |value| value == property.value }
553
+ if(property.value != '' && !property.value.nil? && existingValue.nil?)
554
+ valueOptionsNode.add_child(xml.create_element('Option', property.value))
555
+ end
556
+ values.each { |value|
557
+ valueOptionsNode.add_child(xml.create_element('Option', value))
558
+ }
559
+ end
560
+ end
561
+
562
+ def setActions(property, actions)
563
+ actionsNode = property.xpath('cops:Action')[0]
564
+ if(actions.empty? && !actionsNode.nil?)
565
+ actionsNode.unlink
566
+ elsif(!actions.empty?)
567
+ actionsNode = actionsNode || property.add_child(xml.create_element('Action', {}))
568
+ actionsNode.namespace = xml.root.namespace_definitions.detect{ |ns| ns.prefix == 'cops' }
569
+ actionsNode['ovf:required'] = 'false'
570
+ actionsNode.children.unlink
571
+ actions.each { |action|
572
+ newActionNode = actionsNode.add_child(xml.create_element(action.action_type, {}))
573
+ if(action.action_type == 'FindReplace')
574
+ newActionNode.add_child(xml.create_element('Path', action.path))
575
+ newActionNode.add_child(xml.create_element('Token', action.value))
576
+ elsif(action.action_type == 'Insert')
577
+ newActionNode.add_child(xml.create_element('Path', action.path))
578
+ if(action.value != '' && !action.value.nil?)
579
+ newActionNode.add_child(xml.create_element('LineNumber', action.value))
580
+ end
581
+ elsif(action.action_type == 'Registry')
582
+ newActionNode.add_child(xml.create_element('RegistryPath', action.path))
583
+ elsif(action.action_type == 'Execute')
584
+ newActionNode.add_child(xml.create_element('Path', action.path))
585
+ if(action.value != '' && !action.value.nil?)
586
+ newActionNode.add_child(xml.create_element('Options', action.value))
587
+ end
588
+ end
589
+ }
590
+ end
591
+ end
592
+
593
+ def self.construct_skeleton
594
+ builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
595
+ 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") {
596
+ xml.References{}
597
+ xml.DiskSection{
598
+ xml.Info "Virtual disk information"
599
+ }
600
+ xml.NetworkSection{
601
+ xml.Info "List of logical networks"
602
+ }
603
+ xml.VirtualSystem('ovf:id' => "vm"){
604
+ xml.Info "A virtual machine"
605
+ xml.Name "New Virtual Machine"
606
+ xml.OperatingSystemSection('ovf:id' => "94"){
607
+ xml.Info "The kind of guest operating system"
608
+ }
609
+ xml.VirtualHardwareSection{
610
+ xml.Info "Virtual hardware requirements"
611
+ xml.System{
612
+ xml['vssd'].ElementName "Virtual Hardware Family"
613
+ xml['vssd'].InstanceID "0"
614
+ xml['vssd'].VirtualSystemIdentifier "New Virtual Machine"
615
+ }
616
+ xml.Item{
617
+ xml['rasd'].AllocationUnits "herts * 10^6"
618
+ xml['rasd'].Description "Number of Virtual CPUs"
619
+ xml['rasd'].ElementName "1 Virtual CPU(s)"
620
+ xml['rasd'].InstanceID "1"
621
+ xml['rasd'].ResourceType "3"
622
+ xml['rasd'].VirtualQuantity "1"
623
+ }
624
+ xml.Item{
625
+ xml['rasd'].AllocationUnits "byte * 2^20"
626
+ xml['rasd'].Description "Memory Size"
627
+ xml['rasd'].ElementName "512MB of memory"
628
+ xml['rasd'].InstanceID "2"
629
+ xml['rasd'].ResourceType "4"
630
+ xml['rasd'].VirtualQuantity "512"
631
+ }
632
+ }
633
+ }
634
+ }
635
+ node = Nokogiri::XML::Comment.new(xml.doc, ' skeleton framework constructed by COAT ')
636
+ xml.doc.children[0].add_previous_sibling(node)
637
+ end
638
+ return builder.to_xml
639
+ end
640
+
641
+ def write_xml(file)
642
+ xml.write_xml_to(file)
643
+ end
644
+
645
+ def sign
646
+ node = Nokogiri::XML::Comment.new(xml, ' made with love by the cops ovf authoring tool. ')
647
+ xml.children[0].add_next_sibling(node)
648
+ end
649
+
650
+ def xpath(string)
651
+ puts @xml.xpath(string)
652
+ end
123
653
 
124
654
  end
125
655
 
@@ -185,8 +715,7 @@ end
185
715
  class FileVmPackage < VmPackage
186
716
  def fetch
187
717
  @xml = Nokogiri::XML(File.open(self.url)) do |config|
188
- config.strict.noent
189
- config.strict
718
+ config.noblanks.strict.noent
190
719
  end
191
720
  end
192
721
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ovfparse
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 189
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 7
9
- version: 0.0.7
9
+ - 81
10
+ version: 0.0.81
10
11
  platform: ruby
11
12
  authors:
12
13
  - Jim Barkley
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-09-21 00:00:00 -04:00
18
+ date: 2011-03-14 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: nokogiri
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 5
27
30
  segments:
28
31
  - 1
29
32
  - 4
@@ -63,23 +66,27 @@ rdoc_options: []
63
66
  require_paths:
64
67
  - lib
65
68
  required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
66
70
  requirements:
67
71
  - - ">="
68
72
  - !ruby/object:Gem::Version
73
+ hash: 3
69
74
  segments:
70
75
  - 0
71
76
  version: "0"
72
77
  required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
73
79
  requirements:
74
80
  - - ">="
75
81
  - !ruby/object:Gem::Version
82
+ hash: 3
76
83
  segments:
77
84
  - 0
78
85
  version: "0"
79
86
  requirements: []
80
87
 
81
88
  rubyforge_project:
82
- rubygems_version: 1.3.6
89
+ rubygems_version: 1.6.2
83
90
  signing_key:
84
91
  specification_version: 3
85
92
  summary: Retrieves and parses files in the Open Virtualization Format