virtualbox 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/Readme.md +9 -9
  2. data/VERSION +1 -1
  3. data/docs/GettingStarted.md +11 -11
  4. data/docs/WhatsNew.md +1 -1
  5. data/lib/virtualbox.rb +10 -1
  6. data/lib/virtualbox/abstract_model.rb +47 -29
  7. data/lib/virtualbox/abstract_model/attributable.rb +16 -16
  8. data/lib/virtualbox/abstract_model/dirty.rb +10 -10
  9. data/lib/virtualbox/abstract_model/relatable.rb +22 -22
  10. data/lib/virtualbox/abstract_model/validatable.rb +4 -4
  11. data/lib/virtualbox/attached_device.rb +23 -23
  12. data/lib/virtualbox/command.rb +9 -9
  13. data/lib/virtualbox/dvd.rb +7 -7
  14. data/lib/virtualbox/ext/subclass_listing.rb +1 -1
  15. data/lib/virtualbox/extra_data.rb +17 -17
  16. data/lib/virtualbox/forwarded_port.rb +23 -23
  17. data/lib/virtualbox/hard_drive.rb +27 -27
  18. data/lib/virtualbox/image.rb +25 -18
  19. data/lib/virtualbox/nic.rb +22 -22
  20. data/lib/virtualbox/proxies/collection.rb +4 -4
  21. data/lib/virtualbox/shared_folder.rb +25 -25
  22. data/lib/virtualbox/storage_controller.rb +16 -16
  23. data/lib/virtualbox/vm.rb +95 -42
  24. data/test/virtualbox/abstract_model/attributable_test.rb +28 -28
  25. data/test/virtualbox/abstract_model/dirty_test.rb +13 -13
  26. data/test/virtualbox/abstract_model/relatable_test.rb +36 -36
  27. data/test/virtualbox/abstract_model/validatable_test.rb +22 -22
  28. data/test/virtualbox/abstract_model_test.rb +46 -36
  29. data/test/virtualbox/attached_device_test.rb +47 -47
  30. data/test/virtualbox/command_test.rb +12 -12
  31. data/test/virtualbox/dvd_test.rb +15 -19
  32. data/test/virtualbox/ext/subclass_listing_test.rb +2 -2
  33. data/test/virtualbox/extra_data_test.rb +37 -37
  34. data/test/virtualbox/forwarded_port_test.rb +31 -31
  35. data/test/virtualbox/hard_drive_test.rb +40 -48
  36. data/test/virtualbox/image_test.rb +36 -33
  37. data/test/virtualbox/nic_test.rb +22 -22
  38. data/test/virtualbox/proxies/collection_test.rb +6 -6
  39. data/test/virtualbox/shared_folder_test.rb +36 -36
  40. data/test/virtualbox/storage_controller_test.rb +14 -14
  41. data/test/virtualbox/vm_test.rb +121 -70
  42. data/test/virtualbox_test.rb +19 -0
  43. data/virtualbox.gemspec +5 -3
  44. metadata +4 -2
data/Readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # VirtualBox Ruby Gem
2
2
 
3
- The VirtualBox ruby gem is a library which allows anyone to control VirtualBox
3
+ The VirtualBox ruby gem is a library which allows anyone to control VirtualBox
4
4
  from ruby code! Create, destroy, start, stop, suspend, and resume virtual machines.
5
5
  Also list virtual machines, list hard drives, network devices, etc.
6
6
 
@@ -19,9 +19,9 @@ the gem, you must set the path to your `VBoxManage` binary:
19
19
  ## Basic Usage
20
20
 
21
21
  The virtualbox gem is modeled after ActiveRecord. If you've used ActiveRecord, you'll
22
- feel very comfortable using the virtualbox gem.
22
+ feel very comfortable using the virtualbox gem.
23
23
 
24
- There is a [quick getting started guide](http://mitchellh.github.com/virtualbox/file.GettingStarted.html) to
24
+ There is a [quick getting started guide](http://mitchellh.github.com/virtualbox/file.GettingStarted.html) to
25
25
  get you acquainted with the conventions of the virtualbox gem.
26
26
 
27
27
  Complete documentation can be found at [http://mitchellh.github.com/virtualbox](http://mitchellh.github.com/virtualbox).
@@ -29,29 +29,29 @@ Complete documentation can be found at [http://mitchellh.github.com/virtualbox](
29
29
  Below are some examples:
30
30
 
31
31
  require 'virtualbox'
32
-
32
+
33
33
  vm = VirtualBox::VM.find("my-vm")
34
-
34
+
35
35
  # Let's first print out some basic info about the VM
36
36
  puts "Memory: #{vm.memory}"
37
-
37
+
38
38
  vm.storage_controllers.each do |sc|
39
39
  sc.attached_devices.each do |device|
40
40
  puts "Attached Device: #{device.uuid}"
41
41
  end
42
42
  end
43
-
43
+
44
44
  # Let's modify the memory and name...
45
45
  vm.memory = 360
46
46
  vm.name = "my-renamed-vm"
47
-
47
+
48
48
  # Save it!
49
49
  vm.save
50
50
 
51
51
  Or here is an example of creating a hard drive:
52
52
 
53
53
  require 'virtualbox'
54
-
54
+
55
55
  hd = VirtualBox::HardDrive.new
56
56
  hd.location = "foo.vdi"
57
57
  hd.size = 2000 # megabytes
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -43,7 +43,7 @@ sort, enumerate, etc.
43
43
 
44
44
  drives = VirtualBox::HardDrive.all
45
45
  puts "You have #{drives.length} hard drives!"
46
-
46
+
47
47
  drives.each do |drive|
48
48
  puts "Drive: #{drive.uuid}"
49
49
  end
@@ -54,7 +54,7 @@ of that model exist.
54
54
  ### Find
55
55
 
56
56
  This example uses {VirtualBox::VM}, which will probably be the most common
57
- model you search for.
57
+ model you search for.
58
58
 
59
59
  vm = VirtualBox::VM.find("MyVM")
60
60
  puts "This VM has #{vm.memory} MB of RAM allocated to it."
@@ -76,7 +76,7 @@ dynamically, they don't show up as methods in the documentation. Because of this
76
76
  attributes are listed for every model in their overviews. For examples, see the
77
77
  overviews of {VirtualBox::VM}, {VirtualBox::HardDrive}, etc.
78
78
 
79
- In addition to an attribute list, many models also have _relationships_.
79
+ In addition to an attribute list, many models also have _relationships_.
80
80
  Relationships are, for our purposes, similar enough to attributes that they
81
81
  can be treated the same. Relationship accessing methods are also dynamically
82
82
  generated, so they are listed within the overviews of the models as well (if they
@@ -88,7 +88,7 @@ way, and can therefore be accessed through each other.
88
88
  Reading attributes is simple. Let's use a {VirtualBox::VM} as an example:
89
89
 
90
90
  vm = VirtualBox::VM.find("FooVM")
91
-
91
+
92
92
  # Accessing attributes:
93
93
  vm.memory
94
94
  vm.name
@@ -101,7 +101,7 @@ Relationships are read the exact same way as attributes. Again using a
101
101
  {VirtualBox::VM} as an example:
102
102
 
103
103
  vm = VirtualBox::VM.find("FooVM")
104
-
104
+
105
105
  # storage_controllers is a relationship containing an array of all the
106
106
  # storage controllers on this VM
107
107
  vm.storage_controllers.each do |sc|
@@ -118,7 +118,7 @@ virtualbox models such as {VirtualBox::StorageController}.
118
118
  In addition to simply reading attributes and relationships, most can be modified
119
119
  as well. I say "most" because some attributes are `readonly` and some relationships
120
120
  simply don't support being directly modified (though their objects may, I'll get to
121
- this in a moment). By looking at the attribute list it is easy to spot a readonly
121
+ this in a moment). By looking at the attribute list it is easy to spot a readonly
122
122
  attribute, which will have the `:readonly` option set to `true`. Below is an example
123
123
  of what you might see in the overview of some model:
124
124
 
@@ -153,7 +153,7 @@ you can set it just like an attribute. Below, we use {VirtualBox::AttachedDevice
153
153
  an example:
154
154
 
155
155
  ad = VirtualBox::AttachedDevice.new
156
-
156
+
157
157
  # Attached devices have an image relationship
158
158
  ad.image = VirtualBox::DVD.empty_drive
159
159
 
@@ -170,7 +170,7 @@ relationship itself. The example below uses {VirtualBox::VM}.
170
170
 
171
171
  Saving models is _really_ easy: you simply call `save`. That's all! Well, there are
172
172
  some subtleties, but that's the basic idea. `save` will typically **also save relationships**
173
- so if you modify a relationship object or relationship itself, calling `save` on the
173
+ so if you modify a relationship object or relationship itself, calling `save` on the
174
174
  parent object will typically save the relationships as well. `save` always returns
175
175
  `true` or `false` depending on whether the operation was a success or not. If you'd like
176
176
  instead to know why a `save` failed, you can call the method with a `true` parameter
@@ -180,10 +180,10 @@ if there is a failure. The message on this object contains the reason.
180
180
  Below is an example of saving a simple {VirtualBox::VM} object:
181
181
 
182
182
  vm = VirtualBox::VM.find("FooVM")
183
-
183
+
184
184
  # Double the memory
185
185
  vm.memory = vm.memory.to_i * 2
186
-
186
+
187
187
  # This will return true/false depending on success
188
188
  vm.save
189
189
 
@@ -191,6 +191,6 @@ Below is an example where an exception will be raised if an error occurs:
191
191
 
192
192
  vm = VirtualBox::VM.find("FooVM")
193
193
  vm.memory = "INVALID"
194
-
194
+
195
195
  # This will raise an exception, since the memory is invalid
196
196
  vm.save(true)
data/docs/WhatsNew.md CHANGED
@@ -31,4 +31,4 @@ Read more about port forwarding {VirtualBox::ForwardedPort here}.
31
31
  ## More Ruby Versions Supported!
32
32
 
33
33
  Previously, virtualbox only supported 1.8.7. It now supports 1.8.6 and 1.9.x thanks
34
- to AleksiP.
34
+ to AlekSi.
data/lib/virtualbox.rb CHANGED
@@ -12,4 +12,13 @@ require 'virtualbox/hard_drive'
12
12
  require 'virtualbox/nic'
13
13
  require 'virtualbox/shared_folder'
14
14
  require 'virtualbox/storage_controller'
15
- require 'virtualbox/vm'
15
+ require 'virtualbox/vm'
16
+
17
+ module VirtualBox
18
+ class <<self
19
+ # Returns installed VirtualBox version like '3.1.2r56127'.
20
+ def version
21
+ Command.vboxmanage("-v").chomp.strip
22
+ end
23
+ end
24
+ end
@@ -13,7 +13,7 @@ module VirtualBox
13
13
  include Dirty
14
14
  include Relatable
15
15
  include Validatable
16
-
16
+
17
17
  # Returns a boolean denoting if the record is new or existing. This
18
18
  # method is provided for subclasses to use to differentiate between
19
19
  # creating a new object or saving an existing one. An example of this
@@ -23,53 +23,53 @@ module VirtualBox
23
23
  new_record! if @new_record.nil?
24
24
  @new_record
25
25
  end
26
-
26
+
27
27
  # Explicitly resets the model to a new record. If you're using this
28
28
  # method outside of virtualbox library core, you should really be
29
29
  # asking yourself "why?"
30
30
  def new_record!
31
31
  @new_record = true
32
32
  end
33
-
33
+
34
34
  # Explicitly sets the model to not be a new record. If you're using
35
35
  # this method outside of virtualbox library core, you should really
36
36
  # be asking yourself "why?"
37
37
  def existing_record!
38
38
  @new_record = false
39
39
  end
40
-
40
+
41
41
  # Returns the errors for a model.
42
42
  def errors
43
43
  error_hash = super
44
-
44
+
45
45
  self.class.relationships.each do |name, options|
46
46
  next unless options && options[:klass].respond_to?(:errors_for_relationship)
47
47
  relationship_errors = options[:klass].errors_for_relationship(self, relationship_data[name])
48
-
48
+
49
49
  error_hash.merge!({ :foos => relationship_errors }) if relationship_errors.length > 0
50
50
  end
51
-
51
+
52
52
  error_hash
53
53
  end
54
-
54
+
55
55
  # Validates the model and relationships.
56
56
  def validate(*args)
57
57
  # First clear all previous errors
58
58
  clear_errors
59
-
59
+
60
60
  # Then do the validations
61
61
  failed = false
62
62
  self.class.relationships.each do |name, options|
63
63
  next unless options && options[:klass].respond_to?(:validate_relationship)
64
64
  failed = true if !options[:klass].validate_relationship(self, relationship_data[name], *args)
65
65
  end
66
-
66
+
67
67
  return !failed
68
68
  end
69
-
69
+
70
70
  # Saves the model attributes and relationships.
71
71
  #
72
- # The method can be passed any arbitrary arguments, which are
72
+ # The method can be passed any arbitrary arguments, which are
73
73
  # implementation specific (see {VM#save}, which does this).
74
74
  def save(*args)
75
75
  # Go through changed attributes and call save_attribute for
@@ -79,31 +79,31 @@ module VirtualBox
79
79
  end
80
80
 
81
81
  save_relationships(*args)
82
-
82
+
83
83
  # No longer a new record
84
84
  @new_record = false
85
85
  end
86
-
86
+
87
87
  # Saves a single attribute of the model. This method on the abstract
88
88
  # model does nothing on its own, and is expected to be overridden
89
- # by any subclasses.
89
+ # by any subclasses.
90
90
  #
91
91
  # This method clears the dirty status of the attribute.
92
92
  def save_attribute(key, value, *args)
93
93
  clear_dirty!(key)
94
94
  end
95
-
95
+
96
96
  # Sets the initial attributes from a hash. This method is meant to be used
97
97
  # once to initially setup the attributes. It is **not a mass-assignment**
98
98
  # method for updating attributes.
99
99
  #
100
- # This method does **not** affect dirtiness, but also does not clear it.
101
- # This means that if you call populate_attributes, the same attributes
102
- # that were dirty before the call will be dirty after the call (but no
103
- # more and no less). This distinction is important because most subclasses
104
- # of AbstractModel only save changed attributes, and ignore unchanged
105
- # attributes. Attempting to change attributes through this method will
106
- # cause them to not be saved, which is surely unexpected behaviour for
100
+ # This method does **not** affect dirtiness, but also does not clear it.
101
+ # This means that if you call populate_attributes, the same attributes
102
+ # that were dirty before the call will be dirty after the call (but no
103
+ # more and no less). This distinction is important because most subclasses
104
+ # of AbstractModel only save changed attributes, and ignore unchanged
105
+ # attributes. Attempting to change attributes through this method will
106
+ # cause them to not be saved, which is surely unexpected behaviour for
107
107
  # most users.
108
108
  #
109
109
  # Calling this method will also cause the model to assume that it is not
@@ -111,21 +111,21 @@ module VirtualBox
111
111
  def populate_attributes(attribs)
112
112
  # No longer a new record
113
113
  @new_record = false
114
-
114
+
115
115
  ignore_dirty do
116
116
  super
117
-
117
+
118
118
  populate_relationships(attribs)
119
119
  end
120
- end
121
-
120
+ end
121
+
122
122
  # Overwrites {Attributable#write_attribute} to set the dirty state of
123
123
  # the written attribute. See {Dirty#set_dirty!} as well.
124
124
  def write_attribute(name, value)
125
125
  set_dirty!(name, read_attribute(name), value)
126
126
  super
127
127
  end
128
-
128
+
129
129
  # Overwrites {Relatable#set_relationship} to set the dirty state of the
130
130
  # relationship. See {Dirty#set_dirty!} as well.
131
131
  def set_relationship(key, value)
@@ -133,7 +133,7 @@ module VirtualBox
133
133
  new_value = super
134
134
  set_dirty!(key, existing, new_value)
135
135
  end
136
-
136
+
137
137
  # Destroys the model. The exact behaviour of this method is expected to be
138
138
  # defined on the subclasses. This method on AbstractModel simply
139
139
  # propagates the destroy to the dependent relationships. For more information
@@ -144,5 +144,23 @@ module VirtualBox
144
144
  destroy_relationship(name, *args) if options[:dependent] == :destroy
145
145
  end
146
146
  end
147
+
148
+ # Creates a human-readable format for this model. This method overrides the
149
+ # default `#<class>` syntax since this doesn't work well for AbstractModels.
150
+ # Instead, it abbreviates it, instead showing all the attributes and their
151
+ # values, and `...` for relationships.
152
+ def inspect
153
+ values = []
154
+
155
+ self.class.attributes.each do |name, options|
156
+ values.push("#{name.inspect}=#{read_attribute(name).inspect}")
157
+ end
158
+
159
+ self.class.relationships.each do |name, options|
160
+ values.push("#{name.inspect}=...")
161
+ end
162
+
163
+ "#<#{self.class} #{values.join(", ")}>".strip
164
+ end
147
165
  end
148
166
  end
@@ -9,7 +9,7 @@ module VirtualBox
9
9
  # Make sure to also see the {ClassMethods}.
10
10
  #
11
11
  # ## Defining a Basic Attribute
12
- #
12
+ #
13
13
  # attribute :name
14
14
  #
15
15
  # The example above would put the "name" attribute on the class. This
@@ -27,7 +27,7 @@ module VirtualBox
27
27
  #
28
28
  # The example above allows age to be read, but not written to via the
29
29
  # `age=` method. The attribute is still able to written using
30
- # {#write_attribute} but this is generally only for
30
+ # {#write_attribute} but this is generally only for
31
31
  # inter-class use, and not for users of it.
32
32
  #
33
33
  # ## Defining Default Values
@@ -39,15 +39,15 @@ module VirtualBox
39
39
  #
40
40
  # ## Populating Multiple Attributes
41
41
  #
42
- # Attributes can be mass populated using {#populate_attributes}. Below
42
+ # Attributes can be mass populated using {#populate_attributes}. Below
43
43
  # is an example of the use.
44
44
  #
45
45
  # class Person
46
46
  # include Attributable
47
- #
47
+ #
48
48
  # attribute :name
49
49
  # attribute :age, :readonly => true
50
- #
50
+ #
51
51
  # def initialize
52
52
  # populate_attributes({
53
53
  # :name => "Steven",
@@ -63,7 +63,7 @@ module VirtualBox
63
63
  # ## Custom Populate Keys
64
64
  #
65
65
  # Sometimes the attribute names don't match the keys of the hash that will be
66
- # used to populate it. For this purpose, you can define a custom
66
+ # used to populate it. For this purpose, you can define a custom
67
67
  # `populate_key`. Example:
68
68
  #
69
69
  # attribute :path, :populate_key => :location
@@ -77,11 +77,11 @@ module VirtualBox
77
77
  def self.included(base)
78
78
  base.extend ClassMethods
79
79
  end
80
-
80
+
81
81
  # Defines the class methods for the {Attributable} module. For
82
82
  # detailed overview documentation, see {Attributable}.
83
83
  module ClassMethods
84
- # Defines an attribute on the model.
84
+ # Defines an attribute on the model.
85
85
  #
86
86
  # @param [Symbol] name The name of the attribute, which will also be
87
87
  # used to set the accessor methods.
@@ -94,10 +94,10 @@ module VirtualBox
94
94
  def attribute(name, options = {})
95
95
  name = name.to_sym
96
96
  attributes[name] = options
97
-
97
+
98
98
  # Create the method for reading this attribute
99
99
  define_method(name) { read_attribute(name) }
100
-
100
+
101
101
  # Create the writer method for it unless the attribute is readonly,
102
102
  # then remove the method if it exists
103
103
  if !options[:readonly]
@@ -113,13 +113,13 @@ module VirtualBox
113
113
  def attributes
114
114
  @attributes ||= {}
115
115
  end
116
-
116
+
117
117
  # Used to propagate attributes to subclasses. This method makes sure that
118
118
  # subclasses of a class with {Attributable} included will inherit the
119
119
  # attributes as well, which would be the expected behaviour.
120
120
  def inherited(subclass)
121
121
  super rescue NoMethodError
122
-
122
+
123
123
  attributes.each do |name, option|
124
124
  subclass.attribute(name, option)
125
125
  end
@@ -128,7 +128,7 @@ module VirtualBox
128
128
 
129
129
  # Does the initial population of the various attributes. It will
130
130
  # ignore attributes which are not defined or have no value in the
131
- # hash.
131
+ # hash.
132
132
  #
133
133
  # Population uses the attributes `populate_key` if present to
134
134
  # determine which value to take. Example:
@@ -152,7 +152,7 @@ module VirtualBox
152
152
 
153
153
  # Writes an attribute. This method ignores the `readonly` option
154
154
  # on attribute definitions. This method is mostly meant for
155
- # internal use on setting attributes (including readonly
155
+ # internal use on setting attributes (including readonly
156
156
  # attributes), whereas users of a class which includes this
157
157
  # module should use the accessor methods, such as `name=`.
158
158
  def write_attribute(name, value)
@@ -161,14 +161,14 @@ module VirtualBox
161
161
 
162
162
  # Reads an attribute. This method will return `nil` if the
163
163
  # attribute doesn't exist. If the attribute does exist but
164
- # doesn't have a value set, it'll use the `default` value
164
+ # doesn't have a value set, it'll use the `default` value
165
165
  # if specified.
166
166
  def read_attribute(name)
167
167
  if has_attribute?(name)
168
168
  attributes[name] || self.class.attributes[name][:default]
169
169
  end
170
170
  end
171
-
171
+
172
172
  # Returns a hash of all attributes and their options.
173
173
  def attributes
174
174
  @attribute_values ||= {}