gapinc-rbvmomi 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/.gitignore +11 -0
  2. data/.yardopts +6 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +19 -0
  5. data/README.rdoc +78 -0
  6. data/Rakefile +47 -0
  7. data/VERSION +1 -0
  8. data/bin/rbvmomish +138 -0
  9. data/devel/analyze-vim-declarations.rb +200 -0
  10. data/devel/analyze-xml.rb +46 -0
  11. data/devel/benchmark.rb +117 -0
  12. data/devel/collisions.rb +18 -0
  13. data/devel/merge-internal-vmodl.rb +59 -0
  14. data/examples/annotate.rb +54 -0
  15. data/examples/cached_ovf_deploy.rb +120 -0
  16. data/examples/clone_vm.rb +84 -0
  17. data/examples/create_vm-1.9.rb +93 -0
  18. data/examples/create_vm.rb +93 -0
  19. data/examples/extraConfig.rb +54 -0
  20. data/examples/lease_tool.rb +102 -0
  21. data/examples/logbundle.rb +63 -0
  22. data/examples/logtail.rb +60 -0
  23. data/examples/nfs_datastore.rb +95 -0
  24. data/examples/power.rb +59 -0
  25. data/examples/readme-1.rb +35 -0
  26. data/examples/readme-2.rb +51 -0
  27. data/examples/run.sh +41 -0
  28. data/examples/screenshot.rb +48 -0
  29. data/examples/vdf.rb +81 -0
  30. data/examples/vm_drs_behavior.rb +76 -0
  31. data/lib/rbvmomi/basic_types.rb +373 -0
  32. data/lib/rbvmomi/connection.rb +268 -0
  33. data/lib/rbvmomi/deserialization.rb +238 -0
  34. data/lib/rbvmomi/fault.rb +17 -0
  35. data/lib/rbvmomi/pbm.rb +66 -0
  36. data/lib/rbvmomi/trivial_soap.rb +114 -0
  37. data/lib/rbvmomi/trollop.rb +70 -0
  38. data/lib/rbvmomi/type_loader.rb +136 -0
  39. data/lib/rbvmomi/utils/admission_control.rb +392 -0
  40. data/lib/rbvmomi/utils/deploy.rb +308 -0
  41. data/lib/rbvmomi/utils/leases.rb +142 -0
  42. data/lib/rbvmomi/utils/perfdump.rb +572 -0
  43. data/lib/rbvmomi/version.rb +3 -0
  44. data/lib/rbvmomi/vim/ComputeResource.rb +51 -0
  45. data/lib/rbvmomi/vim/Datacenter.rb +17 -0
  46. data/lib/rbvmomi/vim/Datastore.rb +68 -0
  47. data/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb +75 -0
  48. data/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb +20 -0
  49. data/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb +46 -0
  50. data/lib/rbvmomi/vim/Folder.rb +204 -0
  51. data/lib/rbvmomi/vim/HostSystem.rb +174 -0
  52. data/lib/rbvmomi/vim/ManagedEntity.rb +57 -0
  53. data/lib/rbvmomi/vim/ManagedObject.rb +55 -0
  54. data/lib/rbvmomi/vim/ObjectContent.rb +23 -0
  55. data/lib/rbvmomi/vim/ObjectUpdate.rb +23 -0
  56. data/lib/rbvmomi/vim/OvfManager.rb +107 -0
  57. data/lib/rbvmomi/vim/PerfCounterInfo.rb +26 -0
  58. data/lib/rbvmomi/vim/PerformanceManager.rb +85 -0
  59. data/lib/rbvmomi/vim/PropertyCollector.rb +25 -0
  60. data/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb +30 -0
  61. data/lib/rbvmomi/vim/ResourcePool.rb +55 -0
  62. data/lib/rbvmomi/vim/ServiceInstance.rb +55 -0
  63. data/lib/rbvmomi/vim/Task.rb +65 -0
  64. data/lib/rbvmomi/vim/VirtualMachine.rb +59 -0
  65. data/lib/rbvmomi/vim.rb +99 -0
  66. data/lib/rbvmomi.rb +15 -0
  67. data/test/test_deserialization.rb +380 -0
  68. data/test/test_emit_request.rb +128 -0
  69. data/test/test_exceptions.rb +14 -0
  70. data/test/test_helper.rb +14 -0
  71. data/test/test_misc.rb +24 -0
  72. data/test/test_parse_response.rb +69 -0
  73. data/test/test_serialization.rb +311 -0
  74. data/vmodl.db +0 -0
  75. metadata +175 -0
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ *.swp
2
+ *.swo
3
+ pkg/
4
+ *.gemspec
5
+ vmodl
6
+ doc
7
+ .yardoc
8
+ *.rbc
9
+ coverage
10
+ *.gem
11
+ Gemfile.lock
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --title "RbVmomi - a Ruby interface to the vSphere API"
2
+ --no-private
3
+ --readme README.rdoc
4
+ lib/rbvmomi/vim.rb
5
+ lib/rbvmomi/vim/*.rb
6
+ lib/rbvmomi/trollop.rb
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 VMware, Inc. All Rights Reserved.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,78 @@
1
+ = RbVmomi
2
+
3
+ == Introduction
4
+
5
+ RbVmomi is a Ruby interface to the vSphere API. Like the Perl and Java SDKs,
6
+ you can use it to manage ESX and VirtualCenter servers. The current release
7
+ supports the vSphere 5.0 API. RbVmomi specific documentation is
8
+ online[http://rdoc.info/github/rlane/rbvmomi/master/frames] and is meant to
9
+ be used alongside the official documentation[http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/index.html].
10
+
11
+ == Installation
12
+
13
+ gem install rbvmomi
14
+
15
+ == Usage
16
+
17
+ A simple example of turning on a VM:
18
+
19
+ require 'rbvmomi'
20
+ vim = RbVmomi::VIM.connect host: 'foo', user: 'bar', password: 'baz'
21
+ dc = vim.serviceInstance.find_datacenter("mydatacenter") or fail "datacenter not found"
22
+ vm = dc.find_vm("myvm") or fail "VM not found"
23
+ vm.PowerOnVM_Task.wait_for_completion
24
+
25
+ This code uses several RbVmomi extensions to the vSphere API for concision. The
26
+ expanded snippet below uses only standard API calls and should be familiar to
27
+ users of the Java SDK:
28
+
29
+ require 'rbvmomi'
30
+ vim = RbVmomi::VIM.connect host: 'foo', user: 'bar', password: 'baz'
31
+ rootFolder = vim.serviceInstance.content.rootFolder
32
+ dc = rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter).find { |x| x.name == "mydatacenter" } or fail "datacenter not found"
33
+ vm = dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine).find { |x| x.name == "myvm" } or fail "VM not found"
34
+ task = vm.PowerOnVM_Task
35
+ filter = vim.propertyCollector.CreateFilter(
36
+ spec: {
37
+ propSet: [{ type: 'Task', all: false, pathSet: ['info.state']}],
38
+ objectSet: [{ obj: task }]
39
+ },
40
+ partialUpdates: false
41
+ )
42
+ ver = ''
43
+ while true
44
+ result = vim.propertyCollector.WaitForUpdates(version: ver)
45
+ ver = result.version
46
+ break if ['success', 'error'].member? task.info.state
47
+ end
48
+ filter.DestroyPropertyFilter
49
+ raise task.info.error if task.info.state == 'error'
50
+
51
+ As you can see, the extensions RbVmomi adds can dramatically decrease the code
52
+ needed to perform simple tasks while still letting you use the full power of
53
+ the API when necessary. RbVmomi extensions are often more efficient than a
54
+ naive implementation; for example, the find_vm method on VIM::Datacenter used
55
+ in the first example uses the SearchIndex for fast lookups.
56
+
57
+ A few important points:
58
+
59
+ * All class, method, parameter, and property names match the official documentation[http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/index.html].
60
+ * Properties are exposed as accessor methods.
61
+ * Data object types can usually be inferred from context, so you may use a hash instead.
62
+ * Enumeration values are simply strings.
63
+ * Example code is included in the examples/ directory.
64
+ * A set of helper methods for Trollop is included to speed up development of
65
+ command line apps. See the included examples for usage.
66
+ * If you don't have trusted SSL certificates installed on the host you're
67
+ connecting to, you'll get an +OpenSSL::SSL::SSLError+ "certificate verify failed".
68
+ You can work around this by using the +:insecure+ option to +RbVmomi::VIM.connect+.
69
+ * This is a side project of a VMware employee and is entirely unsupported by VMware.
70
+
71
+ Built-in extensions are under +lib/rbvmomi/vim/+. You are encouraged to
72
+ reopen VIM classes in your applications and add extensions of your own. If you
73
+ write something generally useful please send it to me and I'll add it in.
74
+
75
+ == Development
76
+
77
+ Fork the project on Github and send me a merge request, or send a patch to
78
+ rlane@vmware.com. RbVmomi developers hang out in #rbvmomi on Freenode.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ # require 'rake/testtask'
2
+ # require 'rake/rdoctask'
3
+ require 'rdoc/task'
4
+ require 'yard'
5
+
6
+ # begin
7
+ # require 'jeweler'
8
+ # Jeweler::Tasks.new do |gem|
9
+ # gem.name = "rbvmomi"
10
+ # gem.summary = "Ruby interface to the VMware vSphere API"
11
+ # #gem.description = ""
12
+ # gem.email = "rlane@vmware.com"
13
+ # gem.homepage = "https://github.com/vmware/rbvmomi"
14
+ # gem.authors = ["Rich Lane", "Christian Dickmann"]
15
+ # gem.add_dependency 'nokogiri', '>= 1.4.1'
16
+ # gem.add_dependency 'builder'
17
+ # gem.add_dependency 'trollop'
18
+ # gem.required_ruby_version = '>= 1.8.7'
19
+ # gem.files.include 'vmodl.db'
20
+ # gem.files.include '.yardopts'
21
+ # end
22
+ # rescue LoadError
23
+ # puts "Jeweler not available. Install it with: gem install jeweler"
24
+ # end
25
+ #
26
+ # Rake::TestTask.new do |t|
27
+ # t.libs << "test"
28
+ # t.test_files = FileList['test/test_*.rb']
29
+ # t.verbose = true
30
+ # end
31
+
32
+ YARD::Rake::YardocTask.new
33
+
34
+ # begin
35
+ # require 'rcov/rcovtask'
36
+ # desc 'Measures test coverage using rcov'
37
+ # Rcov::RcovTask.new do |rcov|
38
+ # rcov.pattern = 'test/test_*.rb'
39
+ # rcov.output_dir = 'coverage'
40
+ # rcov.verbose = true
41
+ # rcov.libs << "test"
42
+ # rcov.rcov_opts << '--exclude "gems/*"'
43
+ # end
44
+ # rescue LoadError
45
+ # puts "Rcov not available. Install it with: gem install rcov"
46
+ # end
47
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.6.0
data/bin/rbvmomish ADDED
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env ruby
2
+ # TODO keepalive
3
+ # TODO rc file
4
+ # TODO proxy support?
5
+ require 'trollop'
6
+ require 'readline'
7
+ require 'rbvmomi'
8
+ require 'rbvmomi/trollop'
9
+
10
+ VIM = RbVmomi::VIM
11
+
12
+ opts = Trollop.options do
13
+ banner <<-EOS
14
+ vSphere API console.
15
+
16
+ Usage:
17
+ rbvmomish [options]
18
+
19
+ Predefined methods:
20
+ conn: Returns the VIM connection
21
+ si: Returns the ServiceInstance
22
+ help: Displays this text.
23
+
24
+ Special syntax:
25
+ Adding a '#' suffix to an expression displays information about the type of the
26
+ result, including its properties and methods, instead of the value.
27
+
28
+ VIM connection options:
29
+ EOS
30
+
31
+ rbvmomi_connection_opts
32
+
33
+ text <<-EOS
34
+
35
+ Other options:
36
+ EOS
37
+
38
+ $trollop = self
39
+ end
40
+
41
+ begin
42
+ $vim = VIM.connect opts
43
+ rescue Errno::EHOSTUNREACH
44
+ abort $!.message
45
+ end
46
+
47
+ typenames = VIM.loader.typenames
48
+ Readline.completion_append_character = " "
49
+ Readline.completion_proc = lambda do |word|
50
+ return unless word
51
+ prefix_regex = /^#{Regexp.escape(word)}/
52
+ candidates = typenames.sort
53
+ candidates.find_all { |e| e.match(prefix_regex) }
54
+ end
55
+
56
+ history_fn = "#{ENV['HOME']}/.rbvmomish-history"
57
+ IO.foreach(history_fn) { |l| Readline::HISTORY << l.chomp } rescue nil
58
+ history = File.open(history_fn, 'a')
59
+
60
+ def type name
61
+ klass = VIM.type(name) rescue err("invalid type #{name.inspect}")
62
+ q = lambda { |x| x =~ /^xsd:/ ? $' : x }
63
+ if klass < VIM::DataObject
64
+ puts "Data Object #{klass}"
65
+ klass.full_props_desc.each do |desc|
66
+ puts " #{desc['name']}: #{q[desc['wsdl_type']]}#{desc['is-array'] ? '[]' : ''}"
67
+ end
68
+ elsif klass < VIM::ManagedObject
69
+ puts "Managed Object #{klass}"
70
+ puts
71
+ puts "Properties:"
72
+ klass.full_props_desc.each do |desc|
73
+ puts " #{desc['name']}: #{q[desc['wsdl_type']]}#{desc['is-array'] ? '[]' : ''}"
74
+ end
75
+ puts
76
+ puts "Methods:"
77
+ klass.full_methods_desc.sort_by(&:first).each do |name,desc|
78
+ params = desc['params']
79
+ puts " #{name}(#{params.map { |x| "#{x['name']} : #{q[x['wsdl_type'] || 'void']}#{x['is-array'] ? '[]' : ''}" } * ', '}) : #{q[desc['result']['wsdl_type'] || 'void']}"
80
+ end
81
+ else
82
+ err("cannot introspect type #{klass}")
83
+ end
84
+ nil
85
+ end
86
+
87
+ class UserError < RuntimeError; end
88
+ def err msg
89
+ raise UserError.new(msg)
90
+ end
91
+
92
+ def cookie str
93
+ $vim.cookie = str
94
+ end
95
+
96
+ def conn
97
+ $vim
98
+ end
99
+
100
+ def si
101
+ $vim.serviceInstance
102
+ end
103
+
104
+ def help
105
+ $trollop.educate
106
+ :no_result
107
+ end
108
+
109
+ $binding = $vim.instance_eval { binding }
110
+
111
+ loop do
112
+ begin
113
+ input = Readline.readline("#{opts[:host]}> ", false) or break
114
+ input = input.strip
115
+ next if input.empty?
116
+
117
+ (history.puts input; Readline::HISTORY << input) unless input == Readline::HISTORY.to_a[-1]
118
+
119
+ result = eval(input, $binding)
120
+ if input =~ /\#$/
121
+ type result.class.wsdl_name
122
+ else
123
+ pp result unless result == :no_result
124
+ end
125
+ rescue SystemExit, IOError
126
+ raise
127
+ rescue RuntimeError, RbVmomi::Fault
128
+ puts "#{$!.class}: #{$!.message}"
129
+ puts $!.backtrace * "\n"
130
+ rescue UserError
131
+ puts $!.message
132
+ rescue Interrupt
133
+ puts
134
+ rescue Exception
135
+ puts "#{$!.class}: #{$!.message}"
136
+ puts $!.backtrace * "\n"
137
+ end
138
+ end
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/env ruby
2
+ require 'nokogiri'
3
+
4
+ # :usage => analyze-vim-declarations.rb vim-declarations.xml foo-declarations.xml vmodl.db
5
+
6
+ XML_FNS = ARGV[0...-1]
7
+ abort "must specify path to vim-declarations.xml" if XML_FNS.empty?
8
+ OUT_FN = ARGV[-1] or abort "must specify path to output database"
9
+
10
+ XML_FNS.each do |x|
11
+ abort "XML file #{x} does not exist" unless File.exists? x
12
+ end
13
+
14
+ TYPES = {}
15
+ VERSIONS = []
16
+
17
+ ID2NAME = Hash.new { |h,k| fail "unknown type-id #{k.inspect}" }
18
+
19
+ ID2NAME.merge!({
20
+ 'java.lang.String' => 'xsd:string',
21
+ 'BOOLEAN' => 'xsd:boolean',
22
+ 'BYTE' => 'xsd:byte',
23
+ 'SHORT' => 'xsd:short',
24
+ 'INT' => 'xsd:int',
25
+ 'LONG' => 'xsd:long',
26
+ 'FLOAT' => 'xsd:float',
27
+ 'DOUBLE' => 'xsd:double',
28
+ 'vmodl.DateTime' => 'xsd:dateTime',
29
+ 'vmodl.Binary' => 'xsd:base64Binary',
30
+ 'vmodl.Any' => 'xsd:anyType',
31
+ 'void' => nil,
32
+ })
33
+
34
+ %w(DataObject ManagedObject MethodFault MethodName
35
+ PropertyPath RuntimeFault TypeName).each do |x|
36
+ ID2NAME['vmodl.' + x] = x
37
+ end
38
+
39
+ def handle_data_object node
40
+ if TYPES[node['name']]
41
+ puts "Type #{node['name']} already exists"
42
+ return
43
+ end
44
+
45
+ ID2NAME[node['type-id']] = node['name']
46
+ TYPES[node['name']] = {
47
+ 'kind' => 'data',
48
+ 'base-type-id' => node['base-type-id'],
49
+ 'props' => node.children.select { |x| x.name == 'property' }.map do |property|
50
+ {
51
+ 'name' => property['name'],
52
+ 'type-id-ref' => property['type-id-ref'],
53
+ 'is-optional' => property['is-optional'] ? true : false,
54
+ 'is-array' => property['is-array'] ? true : false,
55
+ 'version-id-ref' => property['version-id-ref'],
56
+ }
57
+ end
58
+ }
59
+ end
60
+
61
+ def handle_managed_object node
62
+ if TYPES[node['name']]
63
+ puts "Type #{node['name']} already exists"
64
+ return
65
+ end
66
+ ID2NAME[node['type-id']] = node['name']
67
+ TYPES[node['name']] = {
68
+ 'kind' => 'managed',
69
+ 'base-type-id' => node['base-type-id'],
70
+ 'props' => node.children.select { |x| x.name == 'property' }.map do |property|
71
+ {
72
+ 'name' => property['name'],
73
+ 'type-id-ref' => property['type-id-ref'],
74
+ 'is-optional' => property['is-optional'] ? true : false,
75
+ 'is-array' => property['is-array'] ? true : false,
76
+ 'version-id-ref' => property['version-id-ref'],
77
+ }
78
+ end,
79
+ 'methods' => Hash[
80
+ node.children.select { |x| x.name == 'method' }.map do |method|
81
+ [method['is-task'] ? "#{method['name']}_Task" : method['name'],
82
+ {
83
+ 'params' => method.children.select { |x| x.name == 'parameter' }.map do |param|
84
+ {
85
+ 'name' => param['name'],
86
+ 'type-id-ref' => param['type-id-ref'],
87
+ 'is-array' => param['is-array'] ? true : false,
88
+ 'is-optional' => param['is-optional'] ? true : false,
89
+ 'version-id-ref' => param['version-id-ref'],
90
+ }
91
+ end,
92
+ 'result' => {
93
+ 'type-id-ref' => method['type-id-ref'],
94
+ 'is-array' => method['is-array'] ? true : false,
95
+ 'is-optional' => method['is-optional'] ? true : false,
96
+ 'is-task' => method['is-task'] ? true : false,
97
+ 'version-id-ref' => method['version-id-ref'],
98
+ }
99
+ }
100
+ ]
101
+ end
102
+ ]
103
+ }
104
+ end
105
+
106
+ def handle_enum node
107
+ if TYPES[node['name']]
108
+ puts "Type #{node['name']} already exists"
109
+ return
110
+ end
111
+
112
+ ID2NAME[node['type-id']] = node['name']
113
+ TYPES[node['name']] = {
114
+ 'kind' => 'enum',
115
+ 'values' => node.children.map { |child| child['name'] },
116
+ }
117
+ end
118
+
119
+ def handle_fault node
120
+ handle_data_object node
121
+ end
122
+
123
+ def handle_version x
124
+ attrs = %w(display-name name service-namespace type-id version-id vmodl-name)
125
+ h = Hash[attrs.map { |k| [k, x[k]] }]
126
+ h['compatible'] = x.children.select(&:element?).map { |y| y.text }
127
+ VERSIONS << h
128
+ end
129
+
130
+ XML_FNS.each do |fn|
131
+ puts "parsing #{fn} ..."
132
+ xml = Nokogiri.parse(File.read(fn), nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS)
133
+ xml.root.at('enums').children.each { |x| handle_enum x }
134
+ xml.root.at('managed-objects').children.each { |x| handle_managed_object x }
135
+ xml.root.at('data-objects').children.each { |x| handle_data_object x }
136
+ xml.root.at('faults').children.each { |x| handle_fault x }
137
+ #xml.root.at('definitions').at('version-types').children.each { |x| handle_version x }
138
+ end
139
+
140
+ munge_fault = lambda { |x| true }
141
+
142
+ TYPES.each do |k,t|
143
+ case t['kind']
144
+ when 'data'
145
+ t['wsdl_base'] = t['base-type-id'] ? ID2NAME[t['base-type-id']] : 'DataObject'
146
+ t.delete 'base-type-id'
147
+ t['props'].each do |x|
148
+ x['wsdl_type'] = ID2NAME[x['type-id-ref']]
149
+ x.delete 'type-id-ref'
150
+ munge_fault[x]
151
+ end
152
+ when 'managed'
153
+ t['wsdl_base'] = t['base-type-id'] ? ID2NAME[t['base-type-id']] : 'ManagedObject'
154
+ t.delete 'base-type-id'
155
+ t['props'].each do |x|
156
+ x['wsdl_type'] = ID2NAME[x['type-id-ref']]
157
+ x.delete 'type-id-ref'
158
+ munge_fault[x]
159
+ end
160
+ t['methods'].each do |mName,x|
161
+ if y = x['result']
162
+ y['wsdl_type'] = ID2NAME[y['type-id-ref']]
163
+ y.delete 'type-id-ref'
164
+ munge_fault[y]
165
+ end
166
+ x['params'].each do |r|
167
+ r['wsdl_type'] = ID2NAME[r['type-id-ref']]
168
+ r.delete 'type-id-ref'
169
+ munge_fault[r]
170
+ end
171
+ end
172
+ when 'enum'
173
+ else fail
174
+ end
175
+ end
176
+
177
+ db = {}
178
+
179
+ TYPES.each do |k,t|
180
+ db[k] = t
181
+ end
182
+
183
+ db['_typenames'] = TYPES.keys
184
+ db['_versions'] = VERSIONS
185
+
186
+ File.open(OUT_FN, 'w') { |io| Marshal.dump db, io }
187
+
188
+ if filename = ENV['VERSION_GRAPH']
189
+ File.open(filename, 'w') do |io|
190
+ io.puts "digraph versions\n{"
191
+ VERSIONS.each do |h|
192
+ io.puts "\"#{h['vmodl-name']}\" [label=\"#{h['vmodl-name']} (#{h['version-id']})\"]"
193
+ h['compatible'].each do |x|
194
+ x =~ /^interface / or fail x
195
+ io.puts "\"#{h['vmodl-name']}\" -> \"#{$'}\""
196
+ end
197
+ end
198
+ io.puts "}\n"
199
+ end
200
+ end
@@ -0,0 +1,46 @@
1
+ require 'nokogiri'
2
+
3
+ # removes line breaks and whitespace between xml nodes.
4
+ def prepare_xml(xml)
5
+ xml = xml.gsub(/\n+/, "")
6
+ xml = xml.gsub(/(>)\s*(<)/, '\1\2')
7
+ end
8
+
9
+ def analyze_xml x, tree
10
+ subtree = (tree[x.name] ||= { :attributes => [], :min_occur => nil, :max_occur => nil })
11
+ attrs = x.attributes.keys.sort
12
+ subtree[:attributes] << attrs unless subtree[:attributes].member? attrs
13
+
14
+ child_occurs = Hash.new 0
15
+ x.children.select(&:element?).each do |c|
16
+ child_occurs[c.name] += 1
17
+ analyze_xml c, subtree
18
+ end
19
+
20
+ subtree.select { |k,v| k.is_a? String }.each do |k,v|
21
+ v[:min_occur] = [v[:min_occur], child_occurs[k]].compact.min
22
+ v[:max_occur] = [v[:max_occur], child_occurs[k]].compact.max
23
+ end
24
+ end
25
+
26
+ def print_tree tree, indent=0
27
+ tree.select { |k,v| k.is_a? String }.sort.each do |k,v|
28
+ attrs = v[:attributes] || []
29
+ min, max = v[:min_occur], v[:max_occur]
30
+ numsym = if min == 0 and max == 0 then fail
31
+ elsif min == 0 and max == 1 then '?'
32
+ elsif min == 0 then '*'
33
+ elsif min == 1 and max == 1 then ''
34
+ else '+'
35
+ end
36
+ puts "#{' '*indent}#{k}#{numsym}: #{attrs.sort.map { |a| "[#{a * ' '}]"} * ', '} {#{min},#{max}}"
37
+ print_tree v, (indent+1)
38
+ end
39
+ end
40
+
41
+ tree = {}
42
+ ARGV.each do |fn|
43
+ nk = Nokogiri(prepare_xml(File.read fn))
44
+ analyze_xml nk.root, tree
45
+ end
46
+ print_tree tree
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env ruby
2
+ require 'tempfile'
3
+
4
+ if ENV['RBVMOMI_COVERAGE'] == '1'
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+ end
8
+
9
+ require 'rbvmomi'
10
+ require 'rbvmomi/deserialization'
11
+ require 'benchmark'
12
+ require 'libxml'
13
+
14
+ NS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'
15
+
16
+ VIM = RbVmomi::VIM
17
+ $conn = VIM.new(:ns => 'urn:vim25', :rev => '4.0')
18
+ raw = File.read(ARGV[0])
19
+
20
+ def diff a, b
21
+ a_io = Tempfile.new 'rbvmomi-diff-a'
22
+ b_io = Tempfile.new 'rbvmomi-diff-b'
23
+ PP.pp a, a_io
24
+ PP.pp b, b_io
25
+ a_io.close
26
+ b_io.close
27
+ system("diff -u #{a_io.path} #{b_io.path}")
28
+ a_io.unlink
29
+ b_io.unlink
30
+ end
31
+
32
+ begin
33
+ deserializer = RbVmomi::OldDeserializer.new($conn)
34
+ end_time = Time.now + 1
35
+ n = 0
36
+ while n == 0 or end_time > Time.now
37
+ deserializer.deserialize Nokogiri::XML(raw).root
38
+ n += 1
39
+ end
40
+ N = n*10
41
+ end
42
+
43
+ puts "iterations: #{N}"
44
+
45
+ parsed_nokogiri = Nokogiri::XML(raw)
46
+ parsed_libxml = LibXML::XML::Parser.string(raw).parse
47
+
48
+ if true
49
+ nokogiri_xml = parsed_nokogiri.root
50
+ libxml_xml = parsed_libxml.root
51
+
52
+ old_nokogiri_result = RbVmomi::OldDeserializer.new($conn).deserialize nokogiri_xml
53
+ new_nokogiri_result = RbVmomi::NewDeserializer.new($conn).deserialize nokogiri_xml
54
+ new_libxml_result = RbVmomi::NewDeserializer.new($conn).deserialize libxml_xml
55
+
56
+ if new_nokogiri_result != old_nokogiri_result
57
+ puts "new_nokogiri_result doesnt match old_nokogiri_result"
58
+ puts "old_nokogiri_result:"
59
+ pp old_nokogiri_result
60
+ puts "new_nokogiri_result:"
61
+ pp new_nokogiri_result
62
+ puts "diff:"
63
+ diff old_nokogiri_result, new_nokogiri_result
64
+ exit 1
65
+ end
66
+
67
+ if new_libxml_result != old_nokogiri_result
68
+ puts "new_libxml_result doesnt match old_nokogiri_result"
69
+ puts "old_nokogiri_result:"
70
+ pp old_nokogiri_result
71
+ puts "new_libxml_result:"
72
+ pp new_libxml_result
73
+ puts "diff:"
74
+ diff old_nokogiri_result, new_libxml_result
75
+ exit 1
76
+ end
77
+
78
+ puts "all results match"
79
+ end
80
+
81
+ Benchmark.bmbm do|b|
82
+ GC.start
83
+ b.report("nokogiri parsing") do
84
+ N.times { Nokogiri::XML(raw) }
85
+ end
86
+
87
+ GC.start
88
+ b.report("libxml parsing") do
89
+ N.times do
90
+ LibXML::XML::Parser.string(raw).parse
91
+ end
92
+ end
93
+
94
+ GC.start
95
+ b.report("old deserialization (nokogiri)") do
96
+ deserializer = RbVmomi::OldDeserializer.new($conn)
97
+ N.times do
98
+ deserializer.deserialize Nokogiri::XML(raw).root
99
+ end
100
+ end
101
+
102
+ GC.start
103
+ b.report("new deserialization (nokogiri)") do
104
+ deserializer = RbVmomi::NewDeserializer.new($conn)
105
+ N.times do
106
+ deserializer.deserialize Nokogiri::XML(raw).root
107
+ end
108
+ end
109
+
110
+ GC.start
111
+ b.report("new deserialization (libxml)") do
112
+ deserializer = RbVmomi::NewDeserializer.new($conn)
113
+ N.times do
114
+ deserializer.deserialize LibXML::XML::Parser.string(raw).parse.root
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # Find collisions between VMODL property names and Ruby methods
3
+ require 'rbvmomi'
4
+ VIM = RbVmomi::VIM
5
+
6
+ conn = VIM.new(:ns => 'urn:vim25', :rev => '4.0')
7
+
8
+ VIM.loader.typenames.each do |name|
9
+ klass = VIM.loader.get name
10
+ next unless klass.respond_to? :kind and [:managed, :data].member? klass.kind
11
+ methods = klass.kind == :managed ?
12
+ RbVmomi::BasicTypes::ObjectWithMethods.instance_methods :
13
+ RbVmomi::BasicTypes::ObjectWithProperties.instance_methods
14
+ klass.props_desc.each do |x|
15
+ name = x['name']
16
+ puts "collision: #{klass}##{name}" if methods.member? name.to_sym
17
+ end
18
+ end