vixen 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ *.gem
3
+ Gemfile.lock
4
+ .rvmrc
5
+ .rspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2012 Jeff Weiss
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/MIT.LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Jeff Weiss
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ Getting Vixen
2
+ =============
3
+
4
+ ```shell
5
+ $ gem install vixen
6
+ ```
7
+
8
+ Using Vixen
9
+ ===========
10
+
11
+ ```ruby
12
+ require 'vixen'
13
+
14
+ Vixen.local_connect.running_vms.each { |vm| puts "Current Snapshot: #{vm.current_snapshot}" }
15
+ ```
16
+
17
+ Vixen can also be used on virtual machines that are not currently active:
18
+
19
+ ```ruby
20
+ require 'vixen'
21
+ path = '/Users/jeff/Documents/Virtual Machines/win2003sat.vmwarevm/Windows Server 2003 Enterprise x64 Edition.vmx'
22
+ puts Vixen.local_connect.open_vm(path).current_snapshot.full_name
23
+ ```
24
+
25
+ Limitations
26
+ -----------
27
+ Vixen currently only supports VMware Fusion 5.
28
+ It also only lists the current snapshot of each of the running virtual machines.
29
+
30
+ See Also
31
+ --------
32
+
33
+ * [Official VMware VIX 1.12 documentation](http://www.vmware.com/support/developer/vix-api/vix112_reference/)
Binary file
data/lib/vixen.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'ffi'
2
+
3
+ module Vixen
4
+ def self.local_connect(login = nil, password = nil)
5
+ connect Vixen::Constants::VixServiceProvider[:vmware_workstation], nil, 0, login, password
6
+ end
7
+
8
+ def self.connect(host_type, hostname, port, username, password)
9
+ handle = Vixen::Bridge.connect(host_type, hostname, port, username, password)
10
+ Vixen::Model::Host.new(handle)
11
+ end
12
+
13
+ end
14
+
15
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
16
+
17
+ require 'vixen/constants'
18
+ require 'vixen/bridge'
19
+ require 'vixen/model/base'
20
+ require 'vixen/model/host'
21
+ require 'vixen/model/vm'
22
+ require 'vixen/model/snapshot'
23
+
@@ -0,0 +1,164 @@
1
+ require 'ffi'
2
+ require 'facter'
3
+
4
+ module Vixen; end
5
+ module Vixen::Bridge
6
+ extend FFI::Library
7
+
8
+ require File.join(File.dirname(__FILE__), 'constants')
9
+ extend Vixen::Constants
10
+ include Vixen::Constants
11
+
12
+
13
+ def self.library_location
14
+ kernel = Facter.value(:kernel) || ''
15
+ arch = Facter.value(:architecture)
16
+ case kernel.downcase
17
+ when 'darwin'
18
+ ext = 'dylib'
19
+ when 'linux'
20
+ ext = 'so'
21
+ when 'windows'
22
+ ext = 'dll'
23
+ end
24
+ File.join(File.dirname(__FILE__), %W[.. .. ext #{kernel} #{arch} libvixAllProducts.#{ext}])
25
+ end
26
+
27
+ ffi_lib library_location
28
+
29
+ typedef :int, :handle
30
+
31
+ callback :VixEventProc, [:handle, :int, :handle, :pointer], :void
32
+
33
+ attach_function :VixHost_Connect, [:int, :int, :string, :int, :string, :string, :int, :handle, :VixEventProc, :pointer], :handle
34
+ attach_function :VixHost_Disconnect, [:handle], :void
35
+ attach_function :VixHost_FindItems, [:handle, :int, :handle, :int, :VixEventProc, :pointer], :handle
36
+ attach_function :VixHost_OpenVM, [:handle, :string, :int, :handle, :VixEventProc, :pointer], :handle
37
+ attach_function :VixHost_RegisterVM, [:handle, :string, :VixEventProc, :pointer], :handle
38
+ attach_function :VixHost_UnregisterVM, [:handle, :string, :VixEventProc, :pointer], :handle
39
+ attach_function :Vix_ReleaseHandle, [:handle], :void
40
+ attach_function :Vix_GetErrorText, [:int, :string], :string
41
+ attach_function :VixJob_Wait, [:handle, :int, :varargs], :int
42
+ attach_function :Vix_GetProperties, [:handle, :int, :varargs], :int
43
+ attach_function :Vix_FreeBuffer, [:pointer], :void
44
+ attach_function :VixVM_GetCurrentSnapshot, [:handle, :pointer], :int
45
+ attach_function :VixSnapshot_GetParent, [:handle, :pointer], :int
46
+
47
+ def self.connect(hostType, hostname, port, username, password)
48
+ job_handle = VixHandle[:invalid]
49
+ host_handle = VixHandle[:invalid]
50
+ job_handle = VixHost_Connect(VixApiVersion[:api_version],
51
+ hostType,
52
+ hostname,
53
+ port,
54
+ username,
55
+ password,
56
+ 0,
57
+ VixHandle[:invalid],
58
+ nil,
59
+ nil)
60
+ host_handle = pointer_to_handle do |host_handle_pointer|
61
+ VixJob_Wait(job_handle,
62
+ VixPropertyId[:job_result_handle],
63
+ :pointer, host_handle_pointer,
64
+ :int, VixPropertyId[:none])
65
+ end
66
+ Vix_ReleaseHandle(job_handle)
67
+ host_handle
68
+ end
69
+
70
+ def self.pointer_to(type, &block)
71
+ pointer = FFI::MemoryPointer.new type, 1
72
+ err = yield pointer
73
+ unless err == VixError[:ok]
74
+ raise "problem executing pointer_to_handle block. (error: %s, %s)" %
75
+ [err, Vix_GetErrorText(err, nil)]
76
+ end
77
+ pointer.send("read_#{type}".to_sym)
78
+ end
79
+
80
+ def self.pointer_to_handle(&block)
81
+ pointer_to :int, &block
82
+ end
83
+
84
+ def self.pointer_to_string(&block)
85
+ pointer_to :pointer, &block
86
+ end
87
+
88
+ def self.running_vms(host_handle)
89
+ available_vms = []
90
+
91
+ collect_proc = Proc.new do |job_handle, event_type, more_event_info, client_data|
92
+ if event_type == VixEventType[:find_item]
93
+ path = get_string_property more_event_info, VixPropertyId[:found_item_location]
94
+ available_vms << path if path
95
+ end
96
+ end
97
+
98
+ job_handle = VixHost_FindItems(host_handle,
99
+ VixFindItemType[:running_vms],
100
+ VixHandle[:invalid],
101
+ -1,
102
+ collect_proc,
103
+ nil)
104
+
105
+ # FIXME: we seem to go into deadlock without this sleep
106
+ # I'm not exactly sure why
107
+ sleep 0.5
108
+ err = VixJob_Wait(job_handle,
109
+ VixPropertyId[:none] )
110
+
111
+ Vix_ReleaseHandle(job_handle)
112
+ available_vms
113
+ end
114
+
115
+ def self.disconnect(handle)
116
+ VixHost_Disconnect(handle)
117
+ end
118
+
119
+ def self.destroy(handle)
120
+ Vix_ReleaseHandle(handle)
121
+ end
122
+
123
+ def self.open_vm(host_handle, vm_path)
124
+ job_handle = VixHost_OpenVM(host_handle,
125
+ vm_path,
126
+ VixVMOpenOptions[:normal],
127
+ VixHandle[:invalid],
128
+ nil,
129
+ nil)
130
+ vm_handle = pointer_to_handle do |vm_handle_pointer|
131
+ VixJob_Wait(job_handle,
132
+ VixPropertyId[:job_result_handle],
133
+ :pointer, vm_handle_pointer,
134
+ :int, VixPropertyId[:none])
135
+ end
136
+ Vix_ReleaseHandle(job_handle)
137
+ vm_handle
138
+ end
139
+
140
+ def self.current_snapshot(vm_handle)
141
+ pointer_to_handle do |snapshot_handle_pointer|
142
+ VixVM_GetCurrentSnapshot(vm_handle, snapshot_handle_pointer)
143
+ end
144
+ end
145
+
146
+ def self.get_parent(snapshot_handle)
147
+ pointer_to_handle do |snapshot_handle_pointer|
148
+ VixSnapshot_GetParent(snapshot_handle, snapshot_handle_pointer)
149
+ end
150
+ end
151
+
152
+ def self.get_string_property(handle, property_id)
153
+ string = pointer_to_string do |string_pointer|
154
+ Vix_GetProperties(handle,
155
+ property_id,
156
+ :pointer, string_pointer,
157
+ :int, VixPropertyId[:none])
158
+ end
159
+ value = string.read_string.force_encoding("UTF-8").dup
160
+ Vix_FreeBuffer(string)
161
+ return value
162
+ end
163
+
164
+ end
@@ -0,0 +1,97 @@
1
+ module Vixen::Constants
2
+ extend FFI::Library
3
+
4
+ VixHandle = enum( :invalid, 0 )
5
+
6
+ VixHandleType = enum( :none, 0,
7
+ :host, 2,
8
+ :vm, 3,
9
+ :network, 5,
10
+ :job, 6,
11
+ :snapshot, 7,
12
+ :property_list, 9,
13
+ :metadata_container, 11 )
14
+
15
+ VixPropertyType = enum( :any, 0,
16
+ :integer, 1,
17
+ :string, 2,
18
+ :bool, 3,
19
+ :handle, 4,
20
+ :int64, 5,
21
+ :blob, 6 )
22
+
23
+ VixError = enum( :ok, 0 )
24
+
25
+ VixPropertyId = enum( :none, 0,
26
+ :meta_data_container, 2,
27
+ :host_hosttype, 50,
28
+ :host_api_version, 51,
29
+ :vm_num_vcpus, 101,
30
+ :vm_vmx_pathname, 103,
31
+ :vm_vmteam_pathname, 105,
32
+ :vm_memory_size, 106,
33
+ :vm_read_only, 107,
34
+ :vm_name, 108,
35
+ :vm_guestos, 109,
36
+ :vm_in_vmteam, 128,
37
+ :vm_power_state, 129,
38
+ :vm_tools_state, 152,
39
+ :vm_is_running, 196,
40
+ :vm_supported_features, 197,
41
+ :vm_ssl_error, 293,
42
+ :job_result_error_code, 3000,
43
+ :job_result_vm_in_group, 3001,
44
+ :job_result_user_message, 3002,
45
+ :job_result_exit_code, 3004,
46
+ :job_result_command_output, 3005,
47
+ :job_result_handle, 3010,
48
+ :job_result_guest_object_exists, 3011,
49
+ :job_result_guest_program_elapsed_time, 3017,
50
+ :job_result_guest_program_exit_code, 3018,
51
+ :job_result_item_name, 3035,
52
+ :job_result_found_item_description, 3036,
53
+ :job_result_shared_folder_const, 3046,
54
+ :job_result_shared_folder_host, 3048,
55
+ :job_result_shared_folder_flags, 3049,
56
+ :job_result_process_id, 3051,
57
+ :job_result_process_owner, 3052,
58
+ :job_result_process_command, 3053,
59
+ :job_result_file_flags, 3054,
60
+ :job_result_process_start_time, 3055,
61
+ :job_result_vm_variable_string, 3056,
62
+ :job_result_process_being_debugged, 3057,
63
+ :job_result_screen_image_size, 3058,
64
+ :job_result_screen_image_data, 3059,
65
+ :job_result_file_size, 3061,
66
+ :job_result_file_mod_time, 3062,
67
+ :job_result_extra_error_info, 3084,
68
+ :found_item_location, 4010,
69
+ :snapshot_displayname, 4200,
70
+ :snapshot_description, 4201,
71
+ :snapshot_powerstate, 4205,
72
+ :guest_sharedfolders_shares_path, 4525,
73
+ :vm_encryption_password, 7001 )
74
+
75
+ VixEventType = enum( :job_completed, 2,
76
+ :job_progress, 3,
77
+ :find_item, 8 )
78
+
79
+ VixFileAttributes = enum( :directory, 1,
80
+ :symlink, 2 )
81
+
82
+ VixHostOptions = enum( :verify_ssl_cert, 0x4000 )
83
+
84
+ VixServiceProvider = enum( :default, 1,
85
+ :vmware_server, 2,
86
+ :vmware_workstation, 3,
87
+ :vmare_player, 4,
88
+ :vmware_vi_server, 10,
89
+ :vmware_workstation_shared, 11 )
90
+
91
+ VixApiVersion = enum( :api_version, -1 )
92
+
93
+ VixFindItemType = enum( :running_vms, 1,
94
+ :registered_vms, 4 )
95
+
96
+ VixVMOpenOptions = enum( :normal, 0x0 )
97
+ end
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'bridge')
2
+ require File.join(File.dirname(__FILE__), '..', 'constants')
3
+
4
+ module Vixen::Model; end
5
+
6
+ class Vixen::Model::Base
7
+ extend Vixen::Constants
8
+ include Vixen::Constants
9
+
10
+ attr_reader :handle
11
+
12
+ def initialize(handle)
13
+ @handle = handle
14
+
15
+ ObjectSpace.define_finalizer( self, self.class.finalize(handle) )
16
+ end
17
+
18
+ def self.finalize(handle)
19
+ proc do
20
+ Vixen::Bridge.destroy(handle)
21
+ end
22
+ end
23
+
24
+ def get_string_property(property_id)
25
+ Vixen::Bridge.get_string_property handle, property_id
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ require File.join(File.dirname(__FILE__), 'base')
2
+ require File.join(File.dirname(__FILE__), 'vm')
3
+
4
+ class Vixen::Model::Host < Vixen::Model::Base
5
+ def self.finalize(handle)
6
+ proc do
7
+ Vixen::Bridge.disconnect(handle)
8
+ Vixen::Bridge.destroy(handle)
9
+ end
10
+ end
11
+
12
+ def open_vm(path)
13
+ Vixen::Model::VM.new(Vixen::Bridge.open_vm handle, path)
14
+ end
15
+
16
+ def running_vms
17
+ vms = []
18
+ paths_of_running_vms.each do |path|
19
+ vms << open_vm(path)
20
+ end
21
+ vms
22
+ end
23
+
24
+ def paths_of_running_vms
25
+ Vixen::Bridge.running_vms(handle) || []
26
+ end
27
+
28
+ end
@@ -0,0 +1,28 @@
1
+ require File.join(File.dirname(__FILE__), 'base')
2
+
3
+ class Vixen::Model::Snapshot < Vixen::Model::Base
4
+ def display_name
5
+ return @display_name unless @display_name.nil?
6
+ @display_name = get_string_property VixPropertyId[:snapshot_displayname]
7
+ end
8
+
9
+ def description
10
+ return @description unless @description.nil?
11
+ @description = get_string_property VixPropertyId[:snapshot_description]
12
+ end
13
+
14
+ def parent
15
+ return @parent unless @parent.nil?
16
+ parent_handle = Vixen::Bridge.get_parent handle
17
+ @parent = parent_handle == VixHandle[:invalid] ? nil : self.class.new(parent_handle)
18
+ end
19
+
20
+ def full_name
21
+ root = parent ? parent.full_name : File::SEPARATOR
22
+ File.join(root, display_name)
23
+ end
24
+
25
+ def to_s
26
+ display_name
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), 'base')
2
+ require File.join(File.dirname(__FILE__), 'snapshot')
3
+
4
+ class Vixen::Model::VM < Vixen::Model::Base
5
+
6
+ def current_snapshot
7
+ Vixen::Model::Snapshot.new(Vixen::Bridge.current_snapshot(handle))
8
+ end
9
+ end
data/vixen.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'vixen'
3
+ s.version = '0.0.3'
4
+ s.summary = 'Ruby bindings for VMware VIX API'
5
+ s.description = <<-EOF
6
+ Vixen is an easy way to interact with VMware virtual machines from Ruby.
7
+
8
+ Vixen is not affliated with or endorsed by VMware.
9
+ EOF
10
+ s.author = 'Jeff Weiss'
11
+ s.email = 'vixen-gem@jeffweiss.org'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.require_paths = ['lib']
14
+ s.platform = Gem::Platform::RUBY
15
+ s.homepage = "https://github.com/jeffweiss/vixen"
16
+ s.licenses = ['Apache-2', 'MIT']
17
+ s.required_ruby_version = '>= 1.8.7'
18
+ s.add_runtime_dependency 'ffi', '>= 1.1.5'
19
+ s.add_runtime_dependency 'facter', '>= 1.6.14'
20
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vixen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jeff Weiss
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ffi
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.5
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.5
30
+ - !ruby/object:Gem::Dependency
31
+ name: facter
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.6.14
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.6.14
46
+ description: ! " Vixen is an easy way to interact with VMware virtual machines from
47
+ Ruby. \n\n Vixen is not affliated with or endorsed by VMware.\n"
48
+ email: vixen-gem@jeffweiss.org
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - LICENSE
55
+ - MIT.LICENSE
56
+ - README.md
57
+ - ext/darwin/x86_64/libvixAllProducts.dylib
58
+ - ext/linux/i386/libvixAllProducts.so
59
+ - ext/linux/x86_64/libvixAllProducts.so
60
+ - lib/vixen.rb
61
+ - lib/vixen/bridge.rb
62
+ - lib/vixen/constants.rb
63
+ - lib/vixen/model/base.rb
64
+ - lib/vixen/model/host.rb
65
+ - lib/vixen/model/snapshot.rb
66
+ - lib/vixen/model/vm.rb
67
+ - vixen.gemspec
68
+ homepage: https://github.com/jeffweiss/vixen
69
+ licenses:
70
+ - Apache-2
71
+ - MIT
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: 1.8.7
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.19
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Ruby bindings for VMware VIX API
94
+ test_files: []