virtualbox 0.1.0

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.
Files changed (36) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +11 -0
  3. data/Rakefile +32 -0
  4. data/Readme.md +75 -0
  5. data/TODO +13 -0
  6. data/VERSION +1 -0
  7. data/lib/virtualbox.rb +11 -0
  8. data/lib/virtualbox/abstract_model.rb +95 -0
  9. data/lib/virtualbox/abstract_model/attributable.rb +193 -0
  10. data/lib/virtualbox/abstract_model/dirty.rb +164 -0
  11. data/lib/virtualbox/abstract_model/relatable.rb +163 -0
  12. data/lib/virtualbox/attached_device.rb +104 -0
  13. data/lib/virtualbox/command.rb +54 -0
  14. data/lib/virtualbox/dvd.rb +31 -0
  15. data/lib/virtualbox/errors.rb +7 -0
  16. data/lib/virtualbox/ext/subclass_listing.rb +24 -0
  17. data/lib/virtualbox/hard_drive.rb +169 -0
  18. data/lib/virtualbox/image.rb +94 -0
  19. data/lib/virtualbox/nic.rb +150 -0
  20. data/lib/virtualbox/storage_controller.rb +122 -0
  21. data/lib/virtualbox/vm.rb +287 -0
  22. data/test/test_helper.rb +25 -0
  23. data/test/virtualbox/abstract_model/attributable_test.rb +150 -0
  24. data/test/virtualbox/abstract_model/dirty_test.rb +66 -0
  25. data/test/virtualbox/abstract_model/relatable_test.rb +141 -0
  26. data/test/virtualbox/abstract_model_test.rb +146 -0
  27. data/test/virtualbox/attached_device_test.rb +92 -0
  28. data/test/virtualbox/command_test.rb +30 -0
  29. data/test/virtualbox/dvd_test.rb +58 -0
  30. data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
  31. data/test/virtualbox/hard_drive_test.rb +161 -0
  32. data/test/virtualbox/image_test.rb +113 -0
  33. data/test/virtualbox/nic_test.rb +119 -0
  34. data/test/virtualbox/storage_controller_test.rb +79 -0
  35. data/test/virtualbox/vm_test.rb +313 -0
  36. metadata +103 -0
@@ -0,0 +1,79 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class StorageControllerTest < Test::Unit::TestCase
4
+ setup do
5
+ @data = {
6
+ :storagecontrollername0 => "foo",
7
+ :storagecontrollermaxportcount0 => 7,
8
+ :storagecontrollername1 => "bar",
9
+ :storagecontrollermaxportcount1 => 4,
10
+ :"foo-0-0" => "yay",
11
+ :"foo-1-0" => "again",
12
+ :"bar-0-0" => "rawr"
13
+ }
14
+
15
+ @caller = mock("caller")
16
+ end
17
+
18
+ context "destroying" do
19
+ setup do
20
+ @value = VirtualBox::StorageController.populate_relationship(@caller, @data)
21
+ @value = @value[0]
22
+ end
23
+
24
+ should "simply call destroy on each object when destroying the relationship" do
25
+ obj_one = mock("one")
26
+ obj_two = mock("two")
27
+
28
+ obj_one.expects(:destroy).with("HELLO").once
29
+ obj_two.expects(:destroy).with("HELLO").once
30
+
31
+ VirtualBox::StorageController.destroy_relationship(self, [obj_one, obj_two], "HELLO")
32
+ end
33
+
34
+ should "call destroy_relationship on AttachedDevices when destroyed" do
35
+ assert !@value.devices.empty?
36
+
37
+ VirtualBox::AttachedDevice.expects(:destroy_relationship).once
38
+ @value.destroy
39
+ end
40
+ end
41
+
42
+ context "populating relationships" do
43
+ should "create the correct amount of objects" do
44
+ value = VirtualBox::StorageController.populate_relationship(@caller, @data)
45
+ assert_equal 2, value.length
46
+ end
47
+
48
+ should "use populate keys when extracting keys" do
49
+ value = VirtualBox::StorageController.new(0, @caller, @data)
50
+ assert_equal "foo", value.name
51
+ assert_equal 7, value.max_ports
52
+ end
53
+
54
+ should "call populate attributes with the merged populate data" do
55
+ VirtualBox::StorageController.any_instance.expects(:extract_devices).returns({ :name => "BAR" })
56
+ value = VirtualBox::StorageController.new(0, @caller, @data)
57
+ assert_equal "BAR", value.name
58
+ end
59
+ end
60
+
61
+ context "extracting related device info" do
62
+ setup do
63
+ @controller = VirtualBox::StorageController.new(0, @caller, @data)
64
+ end
65
+
66
+ should "extract only those keys related to current controller name" do
67
+ data = @controller.extract_devices(0, @data)
68
+ assert data
69
+ assert data.has_key?(:"foo-0-0")
70
+ assert data.has_key?(:"foo-1-0")
71
+ assert !data.has_key?(:"bar-0-0")
72
+
73
+ data = @controller.extract_devices(1, @data)
74
+ assert data
75
+ assert !data.has_key?(:"foo-0-0")
76
+ assert data.has_key?(:"bar-0-0")
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,313 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class VMTest < Test::Unit::TestCase
4
+ setup do
5
+ @raw = <<-showvminfo
6
+ VirtualBox Command Line Management Interface Version 3.1.2
7
+ (C) 2005-2009 Sun Microsystems, Inc.
8
+ All rights reserved.
9
+
10
+ name="foo"
11
+ ostype="Ubuntu"
12
+ UUID="8710d3db-d96a-46ed-9004-59fa891fda90"
13
+ CfgFile="/Users/mitchellh/Library/VirtualBox/Machines/foo/foo.xml"
14
+ hardwareuuid="8710d3db-d96a-46ed-9004-59fa891fda90"
15
+ memory=360
16
+ vram=12
17
+ cpus=1
18
+ synthcpu="off"
19
+ bootmenu="messageandmenu"
20
+ boot1="floppy"
21
+ boot2="dvd"
22
+ boot3="disk"
23
+ boot4="none"
24
+ acpi="on"
25
+ ioapic="off"
26
+ pae="on"
27
+ biossystemtimeoffset=0
28
+ hwvirtex="on"
29
+ hwvirtexexcl="off"
30
+ nestedpaging="off"
31
+ vtxvpid="off"
32
+ VMState="poweroff"
33
+ VMStateChangeTime="2010-01-22T22:02:47.672000000"
34
+ monitorcount=1
35
+ accelerate3d="off"
36
+ accelerate2dvideo="off"
37
+ teleporterenabled="off"
38
+ teleporterport=0
39
+ teleporteraddress="<NULL>"
40
+ teleporterpassword="<NULL>"
41
+ storagecontrollername0="IDE Controller"
42
+ storagecontrollertype0="PIIX4"
43
+ storagecontrollerinstance0="0"
44
+ storagecontrollermaxportcount0="2"
45
+ storagecontrollerportcount0="2"
46
+ storagecontrollername1="Floppy Controller"
47
+ storagecontrollertype1="I82078"
48
+ storagecontrollerinstance1="0"
49
+ storagecontrollermaxportcount1="1"
50
+ storagecontrollerportcount1="1"
51
+ "IDE Controller-0-0"="/Users/mitchellh/Library/VirtualBox/HardDisks/HoboBase.vmdk"
52
+ "IDE Controller-ImageUUID-0-0"="5e090af6-7d71-4f40-8b03-33aa665f9ecf"
53
+ "IDE Controller-0-1"="none"
54
+ "IDE Controller-1-0"="emptydrive"
55
+ "IDE Controller-1-1"="none"
56
+ "Floppy Controller-0-0"="emptydrive"
57
+ "Floppy Controller-0-1"="none"
58
+ bridgeadapter1="en1: AirPort"
59
+ macaddress1="08002771F257"
60
+ cableconnected1="on"
61
+ nic1="bridged"
62
+ nic2="none"
63
+ nic3="none"
64
+ nic4="none"
65
+ nic5="none"
66
+ nic6="none"
67
+ nic7="none"
68
+ nic8="none"
69
+ uart1="off"
70
+ uart2="off"
71
+ audio="none"
72
+ clipboard="bidirectional"
73
+ vrdp="off"
74
+ usb="off"
75
+ showvminfo
76
+
77
+ @name = "foo"
78
+
79
+ # Just to be sure nothing is executed
80
+ VirtualBox::Command.stubs(:execute).returns('')
81
+ end
82
+
83
+ def create_vm
84
+ command_seq = sequence("command_seq")
85
+ VirtualBox::Command.expects(:vboxmanage).with("showvminfo #{@name} --machinereadable").returns(@raw).in_sequence(command_seq)
86
+ VirtualBox::Command.expects(:vboxmanage).with(anything).returns("").at_least(0).in_sequence(command_seq)
87
+ vm = VirtualBox::VM.find(@name)
88
+ assert vm
89
+ vm
90
+ end
91
+
92
+ context "human readable info" do
93
+ should "not pass --machinereadable into the showvminfo command" do
94
+ VirtualBox::Command.expects(:vboxmanage).with("showvminfo #{@name}").once
95
+ VirtualBox::VM.human_info(@name)
96
+ end
97
+ end
98
+
99
+ context "reading the VM state" do
100
+ setup do
101
+ @vm = create_vm
102
+ end
103
+
104
+ should "read the initial state when loading the VM" do
105
+ assert_equal "poweroff", @vm.state
106
+ end
107
+
108
+ should "reload the state if true is passed as a parameter" do
109
+ VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "on" })
110
+ assert_equal "on", @vm.state(true)
111
+ assert_equal "on", @vm.state
112
+ end
113
+ end
114
+
115
+ context "starting and stopping" do
116
+ setup do
117
+ @vm = create_vm
118
+ end
119
+
120
+ should "start a VM with the given type" do
121
+ VirtualBox::Command.expects(:vboxmanage).with("startvm #{@name} --type FOO")
122
+ @vm.start(:FOO)
123
+ end
124
+
125
+ should "stop a VM with a 'poweroff'" do
126
+ VirtualBox::Command.expects(:vboxmanage).with("controlvm #{@name} poweroff")
127
+ @vm.stop
128
+ end
129
+ end
130
+
131
+ context "destroying" do
132
+ setup do
133
+ @vm = create_vm
134
+ end
135
+
136
+ should "destroy all storage controllers before destroying VM" do
137
+ destroy_seq = sequence("destroy_seq")
138
+ VirtualBox::StorageController.expects(:destroy_relationship).in_sequence(destroy_seq)
139
+ VirtualBox::Command.expects(:vboxmanage).with("unregistervm #{@name} --delete").in_sequence(destroy_seq)
140
+ @vm.destroy
141
+ end
142
+ end
143
+
144
+ context "finding all VMs" do
145
+ setup do
146
+ @raw = <<-raw
147
+ "foo" {abcdefg}
148
+ "bar" {zefaldf}
149
+ raw
150
+ end
151
+
152
+ should "list VMs then parse them" do
153
+ all_seq = sequence("all")
154
+ VirtualBox::Command.expects(:vboxmanage).with("list vms").returns(@raw).in_sequence(all_seq)
155
+ VirtualBox::VM.expects(:parse_vm_list).with(@raw).in_sequence(all_seq)
156
+ VirtualBox::VM.all
157
+ end
158
+
159
+ context "parser" do
160
+ should "ignore non-matching lines" do
161
+ assert VirtualBox::VM.parse_vm_list("HEY YOU").empty?
162
+ end
163
+
164
+ should "return VM objects for valid lines" do
165
+ vm_foo = mock("vm_foo")
166
+ vm_bar = mock("vm_bar")
167
+ parse_seq = sequence("parse")
168
+ VirtualBox::VM.expects(:find).with("foo").returns(vm_foo).in_sequence(parse_seq)
169
+ VirtualBox::VM.expects(:find).with("bar").returns(vm_bar).in_sequence(parse_seq)
170
+
171
+ result = VirtualBox::VM.parse_vm_list(@raw)
172
+ assert !result.empty?
173
+ assert_equal 2, result.length
174
+ assert_equal vm_foo, result[0]
175
+ assert_equal vm_bar, result[1]
176
+ end
177
+ end
178
+ end
179
+
180
+ context "importing a VM" do
181
+ setup do
182
+ @raw = <<-raw
183
+ VirtualBox Command Line Management Interface Version 3.1.2
184
+ (C) 2005-2009 Sun Microsystems, Inc.
185
+ All rights reserved.
186
+
187
+ 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
188
+ Interpreting /Users/mitchellh/base.ovf...
189
+ OK.
190
+ Disks: vmdisk1 21474836480 -1 http://www.vmware.com/specifications/vmdk.html#sparse HoboBase.vmdk 379268096 -1 <NULL>
191
+ Virtual system 0:
192
+ 0: Suggested OS type: "Ubuntu"
193
+ (change with "--vsys 0 --ostype <type>"; use "list ostypes" to list all possible values)
194
+ 1: Suggested VM name "Base_1"
195
+ (change with "--vsys 0 --vmname <name>")
196
+ 2: Number of CPUs: 1
197
+ raw
198
+ end
199
+
200
+ should "attempt to find the imported VM" do
201
+ VirtualBox::Command.expects(:vboxmanage).with("import whatever").returns(@raw)
202
+ VirtualBox::VM.expects(:find).with("Base_1").once
203
+ VirtualBox::VM.import("whatever")
204
+ end
205
+
206
+ should "parse the VM name from the raw string" do
207
+ assert_equal "Base_1", VirtualBox::VM.parse_vm_name(@raw)
208
+ end
209
+
210
+ should "return nil on parsing the VM name if its invalid" do
211
+ assert_nil VirtualBox::VM.parse_vm_name("Name foo")
212
+ end
213
+ end
214
+
215
+ context "saving a changed VM" do
216
+ setup do
217
+ @vm = create_vm
218
+ end
219
+
220
+ should "save only the attributes which saved" do
221
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{@name} --ostype Zubuntu")
222
+
223
+ @vm.ostype = "Zubuntu"
224
+ @vm.save
225
+ end
226
+
227
+ should "shell escape saved values" do
228
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{@name} --ostype My\\ Value")
229
+
230
+ @vm.ostype = "My Value"
231
+ @vm.save
232
+ end
233
+
234
+ should "shell escape the string value of a value" do
235
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{@name} --memory 400")
236
+
237
+ @vm.memory = 400
238
+ assert_nothing_raised { @vm.save }
239
+ end
240
+
241
+ should "save name first if changed, then following values should modify new VM" do
242
+ save_seq = sequence("save_seq")
243
+ new_name = "foo2"
244
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{@name} --name #{new_name}").in_sequence(save_seq)
245
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{new_name} --ostype Zubuntu").in_sequence(save_seq)
246
+
247
+ @vm.name = new_name
248
+ @vm.ostype = "Zubuntu"
249
+ @vm.save
250
+ end
251
+ end
252
+
253
+ context "finding a VM by name" do
254
+ setup do
255
+
256
+ @expected = {
257
+ :name => "foo",
258
+ :ostype => "Ubuntu",
259
+ :uuid => "8710d3db-d96a-46ed-9004-59fa891fda90"
260
+ }
261
+
262
+ command_seq = sequence("command_seq)")
263
+ VirtualBox::Command.expects(:vboxmanage).with("showvminfo #{@name} --machinereadable").returns(@raw).in_sequence(command_seq)
264
+ VirtualBox::Command.expects(:vboxmanage).with(anything).returns("").at_least(0).in_sequence(command_seq)
265
+ @vm = VirtualBox::VM.find(@name)
266
+ assert @vm
267
+ end
268
+
269
+ should "return a VM object with proper attributes" do
270
+ @expected.each do |k,v|
271
+ assert_equal v, @vm.read_attribute(k)
272
+ end
273
+ end
274
+
275
+ should "properly load nic relationship" do
276
+ assert @vm.nics
277
+ assert @vm.nics.is_a?(Array)
278
+ assert_equal 8, @vm.nics.length
279
+ end
280
+
281
+ should "properly load storage controller relationship" do
282
+ assert @vm.storage_controllers
283
+ assert @vm.storage_controllers.is_a?(Array)
284
+ assert_equal 2, @vm.storage_controllers.length
285
+ end
286
+ end
287
+
288
+ context "parsing the showvminfo output" do
289
+ should "lowercase and symbolize the keys" do
290
+ result = VirtualBox::VM.parse_vm_info("ZING=Zam")
291
+ assert_equal 1, result.length
292
+ assert_equal "Zam", result[:zing]
293
+ end
294
+
295
+ should "ignore quotes for multi-word keys or values" do
296
+ result = VirtualBox::VM.parse_vm_info('"foo bar"="baz"')
297
+ assert_equal 1, result.length
298
+ assert_equal "baz", result[:"foo bar"]
299
+ end
300
+
301
+ should "ignore the lines which aren't the proper format" do
302
+ result = VirtualBox::VM.parse_vm_info(<<-block)
303
+ This should not be parsed
304
+ Neither should this
305
+
306
+ foo=bar
307
+ block
308
+
309
+ assert_equal 1, result.length
310
+ assert_equal "bar", result[:foo]
311
+ end
312
+ end
313
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: virtualbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mitchell Hashimoto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-24 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Create and modify virtual machines in VirtualBox using pure ruby.
17
+ email: mitchell.hashimoto@gmail.com
18
+ executables:
19
+ - rake
20
+ - rdebug
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - TODO
25
+ files:
26
+ - .gitignore
27
+ - Gemfile
28
+ - Rakefile
29
+ - Readme.md
30
+ - TODO
31
+ - VERSION
32
+ - lib/virtualbox.rb
33
+ - lib/virtualbox/abstract_model.rb
34
+ - lib/virtualbox/abstract_model/attributable.rb
35
+ - lib/virtualbox/abstract_model/dirty.rb
36
+ - lib/virtualbox/abstract_model/relatable.rb
37
+ - lib/virtualbox/attached_device.rb
38
+ - lib/virtualbox/command.rb
39
+ - lib/virtualbox/dvd.rb
40
+ - lib/virtualbox/errors.rb
41
+ - lib/virtualbox/ext/subclass_listing.rb
42
+ - lib/virtualbox/hard_drive.rb
43
+ - lib/virtualbox/image.rb
44
+ - lib/virtualbox/nic.rb
45
+ - lib/virtualbox/storage_controller.rb
46
+ - lib/virtualbox/vm.rb
47
+ - test/test_helper.rb
48
+ - test/virtualbox/abstract_model/attributable_test.rb
49
+ - test/virtualbox/abstract_model/dirty_test.rb
50
+ - test/virtualbox/abstract_model/relatable_test.rb
51
+ - test/virtualbox/abstract_model_test.rb
52
+ - test/virtualbox/attached_device_test.rb
53
+ - test/virtualbox/command_test.rb
54
+ - test/virtualbox/dvd_test.rb
55
+ - test/virtualbox/ext/subclass_listing_test.rb
56
+ - test/virtualbox/hard_drive_test.rb
57
+ - test/virtualbox/image_test.rb
58
+ - test/virtualbox/nic_test.rb
59
+ - test/virtualbox/storage_controller_test.rb
60
+ - test/virtualbox/vm_test.rb
61
+ has_rdoc: true
62
+ homepage: http://github.com/mitchellh/virtualbox
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --charset=UTF-8
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.5
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Create and modify virtual machines in VirtualBox using pure ruby.
89
+ test_files:
90
+ - test/test_helper.rb
91
+ - test/virtualbox/abstract_model/attributable_test.rb
92
+ - test/virtualbox/abstract_model/dirty_test.rb
93
+ - test/virtualbox/abstract_model/relatable_test.rb
94
+ - test/virtualbox/abstract_model_test.rb
95
+ - test/virtualbox/attached_device_test.rb
96
+ - test/virtualbox/command_test.rb
97
+ - test/virtualbox/dvd_test.rb
98
+ - test/virtualbox/ext/subclass_listing_test.rb
99
+ - test/virtualbox/hard_drive_test.rb
100
+ - test/virtualbox/image_test.rb
101
+ - test/virtualbox/nic_test.rb
102
+ - test/virtualbox/storage_controller_test.rb
103
+ - test/virtualbox/vm_test.rb