virtualbox-com 0.9.6

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/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ doc/*
2
+ .yardoc/*
3
+ pkg/*
4
+ test/coverage/*
5
+ .bundle/*
6
+ Gemfile.lock
7
+ test.rb
8
+ *.rbc
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ # Gems required for development only.
6
+ group :development do
7
+ gem "ffi"
8
+ gem "nokogiri"
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Mitchell Hashimoto.
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/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # -*- ruby -*-
2
+ require "rbconfig"
3
+ require "rubygems"
4
+ require "bundler/setup"
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+
data/Readme.md ADDED
@@ -0,0 +1,59 @@
1
+ # VirtualBox-Com Ruby Gem
2
+
3
+ This is a simplified version of the unmaintained virtualbox gem
4
+ by [Mitchell Hashimoto](https://github.com/mitchellh)
5
+
6
+ The VirtualBox::COM ruby gem is a library which allows anyone to control
7
+ VirtualBox from ruby code! Create, destroy, start, stop, suspend, and
8
+ resume virtual machines. Also list virtual machines, list hard
9
+ drives, network devices, etc.
10
+
11
+ ## Installation and Requirements
12
+
13
+ First you need to install [VirtualBox](http://www.virtualbox.org/)
14
+ which is available for Windows, Linux, and OS X. After installation,
15
+ install the gem:
16
+
17
+ sudo gem install virtualbox-com
18
+
19
+ The gem uses the native COM interface with VirtualBox provides to
20
+ communicate with VirtualBox. The gem uses Ruby-FFI to talk to a
21
+ dynamic library. No configuration should be necessary.
22
+
23
+ ## Basic Usage
24
+
25
+ require 'virtualbox-com'
26
+
27
+ lib = VirtualBox::COM
28
+
29
+ puts lib.virtualbox.machines[0].name
30
+ puts lib.virtualbox.find_machine('Windows').groups
31
+
32
+ ## Known Issues or Uncompleted Features
33
+
34
+ All the classes are generated from the VirtualBox.xidl
35
+
36
+ ## Reporting Bugs or Feature Requests
37
+
38
+ Please use the [issue tracker](https://github.com/sdalu/virtualbox-com/issues).
39
+
40
+ ## Contributing
41
+
42
+ If you'd like to contribute to VirtualBox, the first step to developing is to
43
+ clone this repo, get [bundler](http://github.com/carlhuda/bundler) if you
44
+ don't have it already, and do the following:
45
+
46
+ bundle install --relock
47
+ rake
48
+
49
+ This will run the test suite, which should come back all green! Then
50
+ you're good to go!
51
+
52
+ ## Special Thanks
53
+
54
+ These folks went above and beyond with contributions to the virtualbox gem, and
55
+ for that, I have to say "thanks!"
56
+
57
+ * [Mitchell Hashimoto](https://github.com/mitchellh)
58
+ * [Kieran Pilkington](https://github.com/KieranP)
59
+ * [Aleksey Palazhchenko](https://github.com/AlekSi)
@@ -0,0 +1,43 @@
1
+ require 'bundler/setup'
2
+ require 'virtualbox-com'
3
+
4
+ # Shortcut
5
+ lib = VirtualBox::COM
6
+
7
+ # Name of the first VM
8
+ puts lib.virtualbox.machines[0].name
9
+
10
+ # Groups of the VM named 'Windows'
11
+ puts lib.virtualbox.find_machine('Windows').groups
12
+
13
+ # Register a passive listener
14
+ begin
15
+ s = VirtualBox::COM.virtualbox.event_source
16
+ l = s.create_listener
17
+ # Listen on all events with a passive listener
18
+ s.register_listener(l, [ :any ], false)
19
+ while true do
20
+ # Get event
21
+ if e = s.get_event(l, 1000)
22
+ case e.type
23
+ when :on_guest_property_changed
24
+ # If GuestProperyChanged cast the event to the
25
+ # model having the most information
26
+ n = e.cast(:GuestPropertyChangedEvent)
27
+ puts "GuestProperty: #{n.machine_id} / #{n.name} / #{n.value}"
28
+ else
29
+ # Display event type
30
+ puts "Event: #{e.type}"
31
+ end
32
+
33
+ # If event is waitable, acknowlege we have finished with it
34
+ if e.waitable
35
+ e.source.event_processed(l, e)
36
+ end
37
+ end
38
+ end
39
+ rescue VirtualBox::COM::ObjectNotFoundException
40
+ # Could just be because we weren't able to collect data fast
41
+ # enough, so VirtualBox unregistered our listener
42
+ retry
43
+ end
@@ -0,0 +1 @@
1
+ require_relative 'virtualbox/com.rb'
@@ -0,0 +1,51 @@
1
+ module VirtualBox
2
+ module COM
3
+ # Versions of Virtualbox that are supported
4
+ SUPPORTED_VERSIONS = {
5
+ "4.2" => [ "3b2f08eb-b810-4715-bee0-bb06b9880ad2",
6
+ "12f4dcdb-12b2-4ec1-b7cd-ddd9f6c5bf4d" ],
7
+ }
8
+
9
+ # The Model module will hold all the model descriptions that will
10
+ # be loaded according to the VirtualBox version
11
+ module Model
12
+ def self.get(name)
13
+ self.const_get(name, false)
14
+ rescue NameError
15
+ raise ModelNotFoundException, name
16
+ end
17
+
18
+ def self.create(name, *args)
19
+ self.get(name).new(*args)
20
+ end
21
+ end
22
+
23
+ # Information about VirtualBox version
24
+ def self.supported? ; !version.nil? ; end
25
+ def self.version ; virtualbox.version_normalized rescue nil ; end
26
+ def self.revision ; virtualbox.revision.to_s rescue nil ; end
27
+
28
+ # Helpers for inclusion
29
+ def virtualbox ; COM.virtualbox ; end
30
+ def session ; COM.session ; end
31
+ end
32
+ end
33
+
34
+
35
+ # Exceptions
36
+ require_relative 'com/exceptions'
37
+
38
+ # Abstract class for model definitions
39
+ require_relative 'com/abstract_enum'
40
+ require_relative 'com/abstract_interface'
41
+
42
+ # Classes
43
+ require_relative 'com/iid'
44
+
45
+ # Implementation
46
+ # It needs to add the following to VirtualBox::COM
47
+ # - Methods: virtualbox, session
48
+ # - Class : Implementer
49
+ # - Types : INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64,
50
+ # WSTRING, BOOL
51
+ require_relative 'com/xpcomc-ffi'
@@ -0,0 +1,51 @@
1
+ require_relative "abstract_model"
2
+
3
+ module VirtualBox
4
+ module COM
5
+
6
+ # Represents a C enum type. Provides functionality to easily convert
7
+ # an int value to its proper symbol within the enum.
8
+ class AbstractEnum < AbstractModel
9
+ extend Enumerable
10
+
11
+ # Defines the mapping of int => symbol for the given Enum.
12
+ # The parameter to this can be an Array or Hash or anything which
13
+ # respond to `each` and yield a key/value pair.
14
+ # If a value appear more than once, only the first is kept
15
+ # If value is left nil, it will return the current mapping
16
+ def self.map(value = nil)
17
+ if value
18
+ m, r = {}, {}
19
+ if Array === value
20
+ then value.each_index {|i| m[value[i]] = i; r[i] = value[i] }
21
+ else value.each {|k,v| m[k] = v; r[v] ||= k }
22
+ end
23
+ @map, @reverse_map = m, r
24
+ end
25
+
26
+ @map
27
+ end
28
+
29
+ # Returns the symbol associated with the given key
30
+ def self.[](index)
31
+ case index
32
+ when Symbol then @map[index]
33
+ else @reverse_map[index]
34
+ end
35
+ end
36
+
37
+ # Returns the index associated with a value
38
+ def self.index(key)
39
+ @map[key]
40
+ end
41
+
42
+ # Iterate over the enum, yielding each item to a block.
43
+ def self.each
44
+ @map.each do |key, value|
45
+ yield key
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,144 @@
1
+ require_relative "abstract_model"
2
+
3
+ module VirtualBox
4
+ module COM
5
+
6
+ #
7
+ # # Defining an Interface
8
+ #
9
+ # Defining an interface is done by subclassing AbstractInterface and
10
+ # using the provided class methods to define the COM methods and
11
+ # properties. A small example class is shown below:
12
+ #
13
+ # class Time < AbstractInterface
14
+ # function :now, [[:out, :uint]]
15
+ # property :hour, :uint
16
+ # end
17
+ #
18
+ # # Accessing an Interface
19
+ #
20
+ #
21
+ # # Assume `time` was retrieved already
22
+ # puts time.foo.to_s
23
+ # time.hour = 20
24
+ # x = time.now
25
+ #
26
+ # The above example shows how the properties and functions can be used
27
+ # with a given interface.
28
+ #
29
+ class AbstractInterface < AbstractModel
30
+ attr_reader :implementer
31
+
32
+ class << self
33
+
34
+ # Extends the current model with another one.
35
+ # Note that redefining functions or properties is not supported.
36
+ def extends(model)
37
+ Model.get(model).members.each do |spec|
38
+ if h.include?(spec.name)
39
+ raise "redefining of #{spec.name} is not supported"
40
+ end
41
+ h[spec.name] = spec
42
+ end
43
+ rescue ModelNotFoundException
44
+ raise "trying to extend an unknown model (#{model})"
45
+ end
46
+
47
+ # Adds a function to the interface
48
+ def function(name, type, args, opts={})
49
+ h[name] = Spec::Function.new(name, type, args, opts)
50
+ end
51
+
52
+ # Adds a property to the interface
53
+ def property(name, type, opts={})
54
+ h[name] = Spec::Property.new(name, type, opts)
55
+ end
56
+
57
+ # Perform final setup
58
+ def setup
59
+ members.each {|spec| name = spec.name
60
+ case spec
61
+ when Spec::Function
62
+ define_method(name) { |*args|
63
+ @implementer.call_function(spec, *args)
64
+ } unless spec.hide?
65
+ when Spec::Property
66
+ define_method(name) {
67
+ @implementer.read_property(spec)
68
+ } unless spec.hide?
69
+ define_method(:"#{name}=") { |value|
70
+ @implementer.write_property(spec, value)
71
+ } unless spec.hide? || spec.readonly?
72
+ end
73
+ }
74
+ end
75
+
76
+ # Get a member by name
77
+ def member(name)
78
+ h[name]
79
+ end
80
+
81
+ # List of members (Spec::*)
82
+ def members
83
+ h.values
84
+ end
85
+
86
+ # List of functions (Spec::Function)
87
+ def functions
88
+ members.select {|s| s.kind_of?(Spec::Function) }
89
+ end
90
+
91
+ # List if properties (Spec::Property)
92
+ def properties
93
+ members.select {|s| s.kind_of?(Spec::Property) }
94
+ end
95
+
96
+
97
+ private
98
+ def h ; @h ||= {} ; end
99
+ end
100
+
101
+
102
+ # Initializes the interface with the given implementer
103
+ def initialize(*args)
104
+ @args = args
105
+ @implementer = Implementer.new(self, *args)
106
+ end
107
+
108
+
109
+ # Cast to another model
110
+ def cast(name)
111
+ @implementer.cast(name, *@args)
112
+ end
113
+
114
+ # Reads a property with the given name
115
+ def read_property(name)
116
+ spec = self.class.member(name)
117
+ raise "#{name} is not a property" unless spec.kind_of?(Spec::Property)
118
+ @implementer.read_property(spec)
119
+ end
120
+
121
+ # Writes a property with the given name
122
+ def write_property(name, value)
123
+ spec = self.class.member(name)
124
+ raise "#{name} is not a property" unless spec.kind_of?(Spec::Property)
125
+ raise "property #{name} is readonly" if spec.readonly?
126
+ @implementer.write_property(spec, value)
127
+ end
128
+
129
+ # Calls a function with the given name
130
+ def call_function(name, *args)
131
+ spec = self.class.member(name)
132
+ raise "#{name} is not a function" unless spec.kind_of?(Spec::Function)
133
+ @implementer.call_function(spec, args)
134
+ end
135
+
136
+
137
+ # Concise inspect
138
+ def inspect
139
+ "#<#{self.class.name}>"
140
+ end
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,14 @@
1
+ module VirtualBox
2
+ module COM
3
+
4
+ class AbstractModel
5
+ def self.iid(str)
6
+ const_set(:IID, IID.new(str))
7
+ end
8
+
9
+ def self.setup(opts={})
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ module VirtualBox
2
+ module COM
3
+
4
+ class ModelNotFoundException < ::Exception; end
5
+
6
+ class COMException < ::Exception
7
+ attr_accessor :data
8
+
9
+ def initialize(data={})
10
+ @data = data
11
+ super("Error in API call to #{data[:function]}: #{data[:code]}")
12
+ end
13
+ end
14
+
15
+ class NotImplementedException < COMException; end
16
+ class ObjectNotFoundException < COMException; end
17
+ class InvalidVMStateException < COMException; end
18
+ class VMErrorException < COMException; end
19
+ class FileErrorException < COMException; end
20
+ class SubsystemException < COMException; end
21
+ class PDMException < COMException; end
22
+ class InvalidObjectStateException < COMException; end
23
+ class HostErrorException < COMException; end
24
+ class NotSupportedException < COMException; end
25
+ class XMLErrorException < COMException; end
26
+ class InvalidSessionStateException < COMException; end
27
+ class ObjectInUseException < COMException; end
28
+ class InvalidArgException < COMException; end
29
+ class NoInterfaceException < COMException; end
30
+
31
+ end
32
+ end