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
@@ -10,7 +10,7 @@ module VirtualBox
10
10
  # DVD.all
11
11
  #
12
12
  # # Empty Drives
13
- #
13
+ #
14
14
  # Sometimes it is useful to have an empty drive. This is the case where you
15
15
  # may have a DVD drive but it has no disk in it. To create an {AttachedDevice},
16
16
  # an image _must_ be specified, and an empty drive is a simple option. Creating
@@ -25,7 +25,7 @@ module VirtualBox
25
25
  raw = Command.vboxmanage("list dvds")
26
26
  parse_raw(raw)
27
27
  end
28
-
28
+
29
29
  # Returns an empty drive. This is useful for creating new
30
30
  # or modifyingn existing {AttachedDevice} objects and
31
31
  # attaching an empty drive to them.
@@ -35,7 +35,7 @@ module VirtualBox
35
35
  new(:empty_drive)
36
36
  end
37
37
  end
38
-
38
+
39
39
  def initialize(*args)
40
40
  if args.length == 1 && args[0] == :empty_drive
41
41
  @empty_drive = true
@@ -43,7 +43,7 @@ module VirtualBox
43
43
  super
44
44
  end
45
45
  end
46
-
46
+
47
47
  # Override of {Image#empty_drive?}. This will only be true if
48
48
  # the DVD was created with {DVD.empty_drive}.
49
49
  #
@@ -51,12 +51,12 @@ module VirtualBox
51
51
  def empty_drive?
52
52
  @empty_drive || false
53
53
  end
54
-
54
+
55
55
  # Override of {Image#image_type}.
56
56
  def image_type
57
57
  "dvddrive"
58
58
  end
59
-
59
+
60
60
  # Deletes the DVD from VBox managed list and also from disk.
61
61
  # This method will fail if the disk is currently mounted to any
62
62
  # virtual machine. This method also does nothing for empty drives
@@ -68,7 +68,7 @@ module VirtualBox
68
68
  # @return [Boolean] True if command was successful, false otherwise.
69
69
  def destroy(raise_errors=false)
70
70
  return false if empty_drive?
71
-
71
+
72
72
  Command.vboxmanage("closemedium dvd #{uuid} --delete")
73
73
  true
74
74
  rescue Exceptions::CommandFailedException
@@ -3,7 +3,7 @@ module VirtualBox::SubclassListing
3
3
  def self.included(base)
4
4
  base.extend ClassMethods
5
5
  end
6
-
6
+
7
7
  module ClassMethods
8
8
  def subclasses(direct = false)
9
9
  classes = []
@@ -7,7 +7,7 @@ module VirtualBox
7
7
  #
8
8
  # # Extra Data on a Virtual Machine
9
9
  #
10
- # Setting extra data on a virtual machine is easy. All {VM} objects have a
10
+ # Setting extra data on a virtual machine is easy. All {VM} objects have a
11
11
  # `extra_data` relationship which is just a simple ruby hash, so you can treat
12
12
  # it like one! Once the data is set, simply saving the VM will save the
13
13
  # extra data. An example below:
@@ -33,11 +33,11 @@ module VirtualBox
33
33
  #
34
34
  class ExtraData < Hash
35
35
  include AbstractModel::Dirty
36
-
36
+
37
37
  attr_accessor :parent
38
-
38
+
39
39
  @@global_data = nil
40
-
40
+
41
41
  class <<self
42
42
  # Gets the global extra data. This will "cache" the data for
43
43
  # future use unless you set the `reload` paramter to true.
@@ -49,10 +49,10 @@ module VirtualBox
49
49
  raw = Command.vboxmanage("getextradata global enumerate")
50
50
  @@global_data = parse_kv_pairs(raw)
51
51
  end
52
-
52
+
53
53
  @@global_data
54
54
  end
55
-
55
+
56
56
  # Parses the key-value pairs from the extra data enumerated
57
57
  # output.
58
58
  #
@@ -64,11 +64,11 @@ module VirtualBox
64
64
  next unless line =~ /^Key: (.+?), Value: (.+?)$/i
65
65
  data[$1.to_s] = $2.strip.to_s
66
66
  end
67
-
67
+
68
68
  data.clear_dirty!
69
69
  data
70
70
  end
71
-
71
+
72
72
  # Populates a relationship with another model.
73
73
  #
74
74
  # **This method typically won't be used except internally.**
@@ -78,7 +78,7 @@ module VirtualBox
78
78
  raw = Command.vboxmanage("getextradata #{Command.shell_escape(caller.name)} enumerate")
79
79
  parse_kv_pairs(raw, caller)
80
80
  end
81
-
81
+
82
82
  # Saves the relationship. This simply calls {#save} on every
83
83
  # member of the relationship.
84
84
  #
@@ -87,21 +87,21 @@ module VirtualBox
87
87
  data.save
88
88
  end
89
89
  end
90
-
91
- # Initializes an extra data object.
90
+
91
+ # Initializes an extra data object.
92
92
  #
93
93
  # @param [Hash] data Initial attributes to populate.
94
94
  def initialize(parent=nil)
95
95
  @parent = parent || "global"
96
96
  end
97
-
97
+
98
98
  # Set an extradata key-value pair. Overrides ruby hash implementation
99
99
  # to set dirty state. Otherwise that, behaves the same way.
100
100
  def []=(key,value)
101
101
  set_dirty!(key, self[key], value)
102
102
  super
103
103
  end
104
-
104
+
105
105
  # Special accessor for parent name attribute. This returns
106
106
  # either the parent name if its a VM object, otherwise
107
107
  # just returns the default.
@@ -114,7 +114,7 @@ module VirtualBox
114
114
  parent
115
115
  end
116
116
  end
117
-
117
+
118
118
  # Saves extra data. This method does the same thing for both new
119
119
  # and existing extra data, since virtualbox will overwrite old data or
120
120
  # create it if it doesn't exist.
@@ -127,14 +127,14 @@ module VirtualBox
127
127
  Command.vboxmanage("setextradata #{Command.shell_escape(parent_name)} #{Command.shell_escape(key)} #{Command.shell_escape(value[1])}")
128
128
  clear_dirty!(key)
129
129
  end
130
-
130
+
131
131
  true
132
132
  rescue Exceptions::CommandFailedException
133
133
  raise if raise_errors
134
134
  false
135
135
  end
136
-
137
- # Deletes the extra data.
136
+
137
+ # Deletes the extra data.
138
138
  #
139
139
  # @param [Boolean] raise_errors If true, {Exceptions::CommandFailedException}
140
140
  # will be raised if the command failed.
@@ -3,7 +3,7 @@ module VirtualBox
3
3
  # own private router for all virtual machines. Because of this,
4
4
  # the host machine can't access services within the guest machine.
5
5
  # To get around this, NAT supports port forwarding, which allows the
6
- # guest machine services to be forwarded to some port on the host
6
+ # guest machine services to be forwarded to some port on the host
7
7
  # machine. Port forwarding is done completely through {ExtraData}, but
8
8
  # is a complicated enough procedure that this class was made to
9
9
  # faciliate it.
@@ -43,7 +43,7 @@ module VirtualBox
43
43
  #
44
44
  # Properties of the model are exposed using standard ruby instance
45
45
  # methods which are generated on the fly. Because of this, they are not listed
46
- # below as available instance methods.
46
+ # below as available instance methods.
47
47
  #
48
48
  # These attributes can be accessed and modified via standard ruby-style
49
49
  # `instance.attribute` and `instance.attribute=` methods. The attributes are
@@ -74,7 +74,7 @@ module VirtualBox
74
74
  attribute :protocol, :default => "TCP"
75
75
  attribute :guestport
76
76
  attribute :hostport
77
-
77
+
78
78
  class <<self
79
79
  # Populates a relationship with another model.
80
80
  #
@@ -83,10 +83,10 @@ module VirtualBox
83
83
  # @return [Array<ForwardedPort>]
84
84
  def populate_relationship(caller, data)
85
85
  relation = Proxies::Collection.new(caller)
86
-
86
+
87
87
  caller.extra_data.each do |key, value|
88
88
  next unless key =~ /^(VBoxInternal\/Devices\/(.+?)\/(.+?)\/LUN#0\/Config\/(.+?)\/)Protocol$/i
89
-
89
+
90
90
  port = new({
91
91
  :parent => caller,
92
92
  :name => $4.to_s,
@@ -96,15 +96,15 @@ module VirtualBox
96
96
  :guestport => caller.extra_data["#{$1.to_s}GuestPort"],
97
97
  :hostport => caller.extra_data["#{$1.to_s}HostPort"]
98
98
  })
99
-
99
+
100
100
  port.existing_record!
101
-
101
+
102
102
  relation.push(port)
103
103
  end
104
-
104
+
105
105
  relation
106
106
  end
107
-
107
+
108
108
  # Saves the relationship. This simply calls {#save} on every
109
109
  # member of the relationship.
110
110
  #
@@ -115,23 +115,23 @@ module VirtualBox
115
115
  end
116
116
  end
117
117
  end
118
-
118
+
119
119
  # @param [Hash] data The initial attributes to populate.
120
120
  def initialize(data={})
121
121
  super()
122
122
  populate_attributes(data)
123
123
  end
124
-
124
+
125
125
  # Validates a forwarded port.
126
126
  def validate
127
127
  super
128
-
128
+
129
129
  validates_presence_of :parent
130
130
  validates_presence_of :name
131
131
  validates_presence_of :guestport
132
132
  validates_presence_of :hostport
133
133
  end
134
-
134
+
135
135
  # Saves the forwarded port.
136
136
  #
137
137
  # @param [Boolean] raise_errors If true, {Exceptions::CommandFailedException}
@@ -139,25 +139,25 @@ module VirtualBox
139
139
  # @return [Boolean] True if command was successful, false otherwise.
140
140
  def save(raise_errors=false)
141
141
  return true if !new_record? && !changed?
142
-
142
+
143
143
  if !valid?
144
144
  raise Exceptions::ValidationFailedException.new(errors) if raise_errors
145
145
  return false
146
146
  end
147
-
147
+
148
148
  destroy(raise_errors) if name_changed?
149
-
149
+
150
150
  parent.extra_data["#{key_prefix}Protocol"] = protocol
151
151
  parent.extra_data["#{key_prefix}GuestPort"] = guestport
152
152
  parent.extra_data["#{key_prefix}HostPort"] = hostport
153
153
  result = parent.extra_data.save(raise_errors)
154
-
154
+
155
155
  clear_dirty!
156
156
  existing_record!
157
-
157
+
158
158
  result
159
159
  end
160
-
160
+
161
161
  # Destroys the port forwarding mapping.
162
162
  #
163
163
  # @param [Boolean] raise_errors If true, {Exceptions::CommandFailedException}
@@ -170,19 +170,19 @@ module VirtualBox
170
170
  results << parent.extra_data.delete("#{key_prefix(true)}Protocol", raise_errors)
171
171
  results << parent.extra_data.delete("#{key_prefix(true)}GuestPort", raise_errors)
172
172
  results << parent.extra_data.delete("#{key_prefix(true)}HostPort", raise_errors)
173
-
173
+
174
174
  new_record!
175
175
  end
176
-
176
+
177
177
  results.empty? || results.all? { |o| o == true }
178
178
  end
179
-
179
+
180
180
  # Relationship callback when added to a collection. This is automatically
181
181
  # called by any relationship collection when this object is added.
182
182
  def added_to_relationship(parent)
183
183
  write_attribute(:parent, parent)
184
184
  end
185
-
185
+
186
186
  # Returns the prefix to be used for the extra data key. Forwarded ports
187
187
  # are created by simply setting {ExtraData} on a {VM}. This class hides most
188
188
  # of the inner workings of it, but it requires a common prefix. This method
@@ -7,7 +7,7 @@ module VirtualBox
7
7
  # find all or a specific hard drive, respectively. Example below:
8
8
  #
9
9
  # VirtualBox::HardDrive.all
10
- #
10
+ #
11
11
  # Or:
12
12
  #
13
13
  # VirtualBox::HardDrive.find("Foo.vdi")
@@ -49,9 +49,9 @@ module VirtualBox
49
49
  # # Cloning Hard Drives
50
50
  #
51
51
  # Hard drives can just as easily be cloned as they can be created or destroyed.
52
- #
52
+ #
53
53
  # hd = VirtualBox::HardDrive.find("foo")
54
- # cloned_hd = hd.clone("bar")
54
+ # cloned_hd = hd.clone("bar")
55
55
  #
56
56
  # In addition to simply cloning hard drives, this command can be used to
57
57
  # clone to a different format:
@@ -63,13 +63,13 @@ module VirtualBox
63
63
  #
64
64
  # Properties of the model are exposed using standard ruby instance
65
65
  # methods which are generated on the fly. Because of this, they are not listed
66
- # below as available instance methods.
66
+ # below as available instance methods.
67
67
  #
68
68
  # These attributes can be accessed and modified via standard ruby-style
69
69
  # `instance.attribute` and `instance.attribute=` methods. The attributes are
70
70
  # listed below. If you aren't sure what this means or you can't understand
71
71
  # why the below is listed, please read {Attributable}.
72
- #
72
+ #
73
73
  # attribute :uuid, :readonly => true
74
74
  # attribute :location
75
75
  # attribute :accessible, :readonly => true
@@ -79,7 +79,7 @@ module VirtualBox
79
79
  class HardDrive < Image
80
80
  attribute :format, :default => "VDI"
81
81
  attribute :size
82
-
82
+
83
83
  class <<self
84
84
  # Returns an array of all available hard drives as HardDrive
85
85
  # objects.
@@ -89,30 +89,30 @@ module VirtualBox
89
89
  raw = Command.vboxmanage("list hdds")
90
90
  parse_blocks(raw).collect { |v| find(v[:uuid]) }
91
91
  end
92
-
92
+
93
93
  # Finds one specific hard drive by UUID or file name. If the
94
94
  # hard drive can not be found, will return `nil`.
95
95
  #
96
96
  # @return [HardDrive]
97
97
  def find(id)
98
98
  raw = Command.vboxmanage("showhdinfo #{id}")
99
-
99
+
100
100
  # Return nil if the hard drive doesn't exist
101
101
  return nil if raw =~ /VERR_FILE_NOT_FOUND/
102
-
102
+
103
103
  data = raw.split(/\n\n/).collect { |v| parse_block(v) }.find { |v| !v.nil? }
104
-
104
+
105
105
  # Set equivalent fields
106
106
  data[:format] = data[:"storage format"]
107
107
  data[:size] = data[:"logical size"].split(/\s+/)[0] if data.has_key?(:"logical size")
108
-
108
+
109
109
  # Return new object
110
110
  new(data)
111
111
  end
112
112
  end
113
-
113
+
114
114
  # Clone hard drive, possibly also converting formats. All formats
115
- # supported by your local VirtualBox installation are supported
115
+ # supported by your local VirtualBox installation are supported
116
116
  # here. If no format is specified, the format of the source drive
117
117
  # will be used.
118
118
  #
@@ -126,27 +126,27 @@ module VirtualBox
126
126
  def clone(outputfile, format="VDI", raise_errors=false)
127
127
  raw = Command.vboxmanage("clonehd #{uuid} #{Command.shell_escape(outputfile)} --format #{format} --remember")
128
128
  return nil unless raw =~ /UUID: (.+?)$/
129
-
129
+
130
130
  self.class.find($1.to_s)
131
131
  rescue Exceptions::CommandFailedException
132
132
  raise if raise_errors
133
133
  nil
134
134
  end
135
-
135
+
136
136
  # Override of {Image#image_type}.
137
137
  def image_type
138
138
  "hdd"
139
139
  end
140
-
140
+
141
141
  # Validates a hard drive.
142
142
  def validate
143
143
  super
144
-
144
+
145
145
  validates_presence_of :format
146
146
  validates_presence_of :size
147
147
  end
148
-
149
- # Creates a new hard drive.
148
+
149
+ # Creates a new hard drive.
150
150
  #
151
151
  # **This method should NEVER be called. Call {#save} instead.**
152
152
  #
@@ -158,25 +158,25 @@ module VirtualBox
158
158
  raise Exceptions::ValidationFailedException.new(errors) if raise_errors
159
159
  return false
160
160
  end
161
-
161
+
162
162
  raw = Command.vboxmanage("createhd --filename #{location} --size #{size} --format #{read_attribute(:format)} --remember")
163
163
  return nil unless raw =~ /UUID: (.+?)$/
164
-
164
+
165
165
  # Just replace our attributes with the newly created ones. This also
166
166
  # will set new_record to false.
167
167
  populate_attributes(self.class.find($1.to_s).attributes)
168
-
168
+
169
169
  # Return the success of the command
170
170
  true
171
171
  rescue Exceptions::CommandFailedException
172
172
  raise if raise_errors
173
173
  false
174
174
  end
175
-
175
+
176
176
  # Saves the hard drive object. If the hard drive is new,
177
177
  # this will create a new hard drive. Otherwise, it will
178
178
  # save any other details about the existing hard drive.
179
- #
179
+ #
180
180
  # Currently, **saving existing hard drives does nothing**.
181
181
  # This is a limitation of VirtualBox, rather than the library itself.
182
182
  #
@@ -191,10 +191,10 @@ module VirtualBox
191
191
  super
192
192
  end
193
193
  end
194
-
194
+
195
195
  # Destroys the hard drive. This deletes the hard drive off
196
- # of disk.
197
- #
196
+ # of disk.
197
+ #
198
198
  # **This operation is not reversable.**
199
199
  #
200
200
  # @param [Boolean] raise_errors If true, {Exceptions::CommandFailedException}