virtualbox 0.7.3 → 0.7.4
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/Gemfile +1 -1
- data/VERSION +1 -1
- data/features/step_definitions/abstract_model_steps.rb +5 -1
- data/features/step_definitions/nat_engine_steps.rb +76 -0
- data/features/step_definitions/shared_folder_steps.rb +19 -0
- data/features/step_definitions/snapshot_steps.rb +74 -0
- data/features/support/env.rb +6 -0
- data/features/support/helpers.rb +16 -1
- data/features/support/ordered_hash.rb +49 -0
- data/features/support/vboxmanage.rb +82 -1
- data/features/vm_nat_engine.feature +57 -0
- data/features/vm_shared_folders.feature +13 -0
- data/features/vm_snapshots.feature +29 -0
- data/lib/virtualbox/abstract_model.rb +23 -7
- data/lib/virtualbox/abstract_model/relatable.rb +6 -2
- data/lib/virtualbox/abstract_model/validatable.rb +1 -1
- data/lib/virtualbox/com/mscom_interface.rb +21 -2
- data/lib/virtualbox/nat_forwarded_port.rb +5 -5
- data/lib/virtualbox/network_adapter.rb +27 -12
- data/lib/virtualbox/proxies/collection.rb +8 -0
- data/lib/virtualbox/shared_folder.rb +3 -3
- data/test/virtualbox/abstract_model/relatable_test.rb +7 -7
- data/test/virtualbox/abstract_model_test.rb +40 -0
- data/test/virtualbox/nat_forwarded_port_test.rb +9 -3
- data/test/virtualbox/proxies/collection_test.rb +15 -0
- data/test/virtualbox/shared_folder_test.rb +7 -1
- data/virtualbox.gemspec +50 -45
- metadata +56 -44
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.4
|
@@ -1,7 +1,11 @@
|
|
1
|
-
Given /the "(.+?)" relationship
|
1
|
+
Given /the "(.+?)" relationship$/ do |relationship|
|
2
2
|
@relationship = @model.send(relationship)
|
3
3
|
end
|
4
4
|
|
5
|
+
Given /the "(.+?)" relationship on collection item "(.+?)"/ do |key, index|
|
6
|
+
@relationship = @relationship[index.to_i - 1].send(key)
|
7
|
+
end
|
8
|
+
|
5
9
|
Given /I reload the model/ do
|
6
10
|
@model.reload
|
7
11
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
Given /the forwarded ports are cleared/ do
|
2
|
+
VBoxManage.network_adapters(@output).each_with_index do |obj, i|
|
3
|
+
VBoxManage.forwarded_ports(@output, i+1).each do |name, data|
|
4
|
+
VBoxManage.execute("modifyvm", @name, "--natpf#{i+1}", "delete", name)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /I read the adapter in slot "(.+?)"$/ do |slot|
|
10
|
+
@slot = slot.to_i
|
11
|
+
@adapter = VBoxManage.network_adapters(@output)[slot.to_i]
|
12
|
+
@adapter.should_not be_nil
|
13
|
+
|
14
|
+
@relationship = @model.network_adapters[slot.to_i - 1].nat_driver
|
15
|
+
end
|
16
|
+
|
17
|
+
Given /I create a forwarded port named "(.+?)" from "(.+?)" to "(.+?)" via VBoxManage/ do |name, guest, host|
|
18
|
+
fp_string = "#{name},tcp,,#{host},,#{guest}"
|
19
|
+
VBoxManage.execute("modifyvm", @name, "--natpf#{@slot}", fp_string)
|
20
|
+
end
|
21
|
+
|
22
|
+
When /I create a forwarded port named "(.+?)" from "(.+?)" to "(.+?)"$/ do |name, guest, host|
|
23
|
+
@object = VirtualBox::NATForwardedPort.new
|
24
|
+
@object.name = name
|
25
|
+
@object.guestport = guest.to_i
|
26
|
+
@object.hostport = host.to_i
|
27
|
+
|
28
|
+
@relationship.forwarded_ports << @object
|
29
|
+
end
|
30
|
+
|
31
|
+
When /I update the forwarded port named "(.+?)":/ do |name, table|
|
32
|
+
fp = @relationship.forwarded_ports.find { |fp| fp.name == name }
|
33
|
+
fp.should_not be_nil
|
34
|
+
|
35
|
+
table.hashes.each do |hash|
|
36
|
+
value = hash["value"]
|
37
|
+
value = value.to_i if %W[hostport guestport].include?(hash["attribute"])
|
38
|
+
fp.send("#{hash["attribute"]}=", value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
When /I delete the forwarded port named "(.+?)"/ do |name|
|
43
|
+
@relationship.forwarded_ports.each do |fp|
|
44
|
+
if fp.name == name
|
45
|
+
fp.destroy
|
46
|
+
break
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Then /the NAT network should exist/ do
|
52
|
+
# Temporary until we find something to really test
|
53
|
+
@relationship.should_not be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
Then /the forwarded port "(.+?)" should exist/ do |name|
|
57
|
+
ports = VBoxManage.forwarded_ports(@output, @slot)
|
58
|
+
ports.should have_key(name)
|
59
|
+
end
|
60
|
+
|
61
|
+
Then /the forwarded port "(.+?)" should not exist/ do |name|
|
62
|
+
ports = VBoxManage.forwarded_ports(@output, @slot)
|
63
|
+
ports.should_not have_key(name)
|
64
|
+
end
|
65
|
+
|
66
|
+
Then /the forwarded ports should match/ do
|
67
|
+
ports = VBoxManage.forwarded_ports(@output, @slot)
|
68
|
+
|
69
|
+
@relationship.forwarded_ports.length.should == ports.length
|
70
|
+
@relationship.forwarded_ports.each do |fp|
|
71
|
+
port = ports[fp.name]
|
72
|
+
port.should_not be_nil
|
73
|
+
|
74
|
+
test_mappings(FORWARDED_PORT_MAPPINGS, fp, port)
|
75
|
+
end
|
76
|
+
end
|
@@ -4,6 +4,12 @@ Given /I add a shared folder "(.+?)" with path "(.+?)" via VBoxManage/ do |name,
|
|
4
4
|
"--hostpath", hostpath)
|
5
5
|
end
|
6
6
|
|
7
|
+
Given /I remove all shared folders/ do
|
8
|
+
VBoxManage.shared_folders(@output).each do |name, folder|
|
9
|
+
Given %Q[I delete the shared folder "#{name}" via VBoxManage]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
Given /I delete the shared folder "(.+?)" via VBoxManage/ do |name|
|
8
14
|
VBoxManage.execute("sharedfolder", "remove", @name,
|
9
15
|
"--name", name)
|
@@ -35,12 +41,25 @@ When /I create a new shared folder "(.+?)" with path "(.+?)"/ do |name,hostpath|
|
|
35
41
|
@new_record.host_path = hostpath
|
36
42
|
end
|
37
43
|
|
44
|
+
When /I update the shared folder named "(.+?)":/ do |name, table|
|
45
|
+
object = @relationship.find { |o| o.name == name }
|
46
|
+
object.should_not be_nil
|
47
|
+
|
48
|
+
table.hashes.each do |hash|
|
49
|
+
object.send("#{hash["attribute"]}=", hash["value"])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
38
53
|
When /I delete the shared folder "(.+?)"$/ do |name|
|
39
54
|
@relationship.each do |sf|
|
40
55
|
sf.destroy if sf.name == name
|
41
56
|
end
|
42
57
|
end
|
43
58
|
|
59
|
+
Then /the shared folder "(.+?)" should exist/ do |name|
|
60
|
+
VBoxManage.shared_folders(@output).keys.should include(name)
|
61
|
+
end
|
62
|
+
|
44
63
|
Then /the shared folder "(.+?)" should not exist/ do |name|
|
45
64
|
VBoxManage.shared_folders(@output).keys.should_not include(name)
|
46
65
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
Given /the snapshots are cleared/ do
|
2
|
+
snapshot_map(VBoxManage.snapshots(@output)) do |snapshot|
|
3
|
+
VBoxManage.execute("snapshot", @name, "delete", snapshot[:name])
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
Given /the following snapshot tree is created:$/ do |tree|
|
8
|
+
tree.hashes.each do |hash|
|
9
|
+
restore_parent = lambda do
|
10
|
+
VBoxManage.execute("snapshot", @name, "restore", hash["key"])
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
restore_parent.call
|
15
|
+
rescue Exception
|
16
|
+
VBoxManage.execute("snapshot", @name, "take", hash["key"])
|
17
|
+
end
|
18
|
+
|
19
|
+
hash["children"].split(",").each do |child|
|
20
|
+
VBoxManage.execute("snapshot", @name, "take", child)
|
21
|
+
restore_parent.call
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Given /the snapshot "(.+?)" is created/ do |name|
|
27
|
+
VBoxManage.execute("snapshot", @name, "take", name)
|
28
|
+
end
|
29
|
+
|
30
|
+
When /I find the snapshot named "(.+?)"/ do |name|
|
31
|
+
@snapshot = @model.find_snapshot(name)
|
32
|
+
@snapshot.should be
|
33
|
+
end
|
34
|
+
|
35
|
+
When /I take a snapshot "(.+?)"/ do |name|
|
36
|
+
@model.take_snapshot(name)
|
37
|
+
end
|
38
|
+
|
39
|
+
When /I destroy the snapshot/ do
|
40
|
+
@snapshot.destroy
|
41
|
+
end
|
42
|
+
|
43
|
+
Then /the snapshot "(.+?)" should exist/ do |name|
|
44
|
+
result = false
|
45
|
+
snapshot_map(VBoxManage.snapshots(@output)) do |snapshot|
|
46
|
+
result = true if snapshot[:name] == name
|
47
|
+
end
|
48
|
+
|
49
|
+
result.should be
|
50
|
+
end
|
51
|
+
|
52
|
+
Then /the snapshot "(.+?)" should not exist/ do |name|
|
53
|
+
result = false
|
54
|
+
snapshot_map(VBoxManage.snapshots(@output)) do |snapshot|
|
55
|
+
result = true if snapshot[:name] == name
|
56
|
+
end
|
57
|
+
|
58
|
+
result.should_not be
|
59
|
+
end
|
60
|
+
|
61
|
+
Then /the snapshots should match/ do
|
62
|
+
@root = @model.root_snapshot
|
63
|
+
|
64
|
+
match_tester = lambda do |current, expected|
|
65
|
+
current.uuid.should == expected[:uuid]
|
66
|
+
current.children.length.should == expected[:children].length
|
67
|
+
|
68
|
+
current.children.each_with_index do |current_child, i|
|
69
|
+
match_tester.call(current_child, expected[:children][i])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
match_tester.call(@root, VBoxManage.snapshots(@output))
|
74
|
+
end
|
data/features/support/env.rb
CHANGED
data/features/support/helpers.rb
CHANGED
@@ -3,7 +3,7 @@ module VirtualBox
|
|
3
3
|
# Tests that given a mappings hash (see `VM_MAPPINGS` in env.rb),
|
4
4
|
# a model, and an output hash (string to string), that all the
|
5
5
|
# mappings from model match output.
|
6
|
-
def test_mappings(mappings, model, output
|
6
|
+
def test_mappings(mappings, model, output)
|
7
7
|
mappings.each do |model_key, output_key|
|
8
8
|
value = model.send(model_key)
|
9
9
|
|
@@ -17,6 +17,21 @@ module VirtualBox
|
|
17
17
|
value.to_s.should == output_value
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
# Applies a function to every snapshot.
|
22
|
+
def snapshot_map(snapshots, &block)
|
23
|
+
applier = lambda do |snapshot|
|
24
|
+
return if !snapshot || snapshot.empty?
|
25
|
+
|
26
|
+
snapshot[:children].each do |child|
|
27
|
+
applier.call(child)
|
28
|
+
end
|
29
|
+
|
30
|
+
block.call(snapshot)
|
31
|
+
end
|
32
|
+
|
33
|
+
applier.call(snapshots)
|
34
|
+
end
|
20
35
|
end
|
21
36
|
end
|
22
37
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# A super simple ordered hash implementation. This class probably
|
2
|
+
# isn't useful outside of these testing scripts, since only the bare
|
3
|
+
# minimum is implemented.
|
4
|
+
#
|
5
|
+
# The ordered hash is implemented by keeping the key/values in an
|
6
|
+
# array where each element is an array of format [key,value]. This
|
7
|
+
# forces the keys to be in the proper order, paired with their
|
8
|
+
# values.
|
9
|
+
class OrderedHash
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@items = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def []=(key,value)
|
17
|
+
# Try to update it in the array if it exists
|
18
|
+
@items.each_with_index do |data, index|
|
19
|
+
return @items[index][1] = value if data[0] == key
|
20
|
+
end
|
21
|
+
|
22
|
+
# Otherwise just add it to the list
|
23
|
+
@items << [key, value]
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
@items.each do |k, v|
|
28
|
+
return v if k == key
|
29
|
+
end
|
30
|
+
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def each(&block)
|
35
|
+
@items.each(&block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def empty?
|
39
|
+
@items.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_key?(key)
|
43
|
+
@items.each do |k,v|
|
44
|
+
return true if k == key
|
45
|
+
end
|
46
|
+
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
@@ -32,7 +32,7 @@ class VBoxManage
|
|
32
32
|
""
|
33
33
|
end
|
34
34
|
|
35
|
-
output.split("\n").inject(
|
35
|
+
output.split("\n").inject(OrderedHash.new) do |acc, line|
|
36
36
|
if line =~ /^"?(.+?)"?=(.+?)$/
|
37
37
|
key = $1.to_s
|
38
38
|
value = $2.to_s
|
@@ -106,5 +106,86 @@ class VBoxManage
|
|
106
106
|
acc
|
107
107
|
end
|
108
108
|
end
|
109
|
+
|
110
|
+
# Parses the forwarded ports out of the VM info output and returns
|
111
|
+
# it in a hash.
|
112
|
+
def forwarded_ports(info, slot)
|
113
|
+
seen = false
|
114
|
+
info.inject({}) do |acc, data|
|
115
|
+
k,v = data
|
116
|
+
|
117
|
+
seen = true if k == "nic#{slot}"
|
118
|
+
if seen && k =~ /^Forwarding\((\d+)\)$/
|
119
|
+
keys = [:name, :protocol, :hostip, :hostport, :guestip, :guestport]
|
120
|
+
v = v.split(",")
|
121
|
+
|
122
|
+
temp = {}
|
123
|
+
keys.each_with_index do |key, i|
|
124
|
+
temp[key] = v[i]
|
125
|
+
end
|
126
|
+
|
127
|
+
acc[temp.delete(:name)] = temp
|
128
|
+
end
|
129
|
+
|
130
|
+
acc
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Parses the snapshots out of the VM info output and returns it in
|
135
|
+
# a hash.
|
136
|
+
def snapshots(info)
|
137
|
+
info.inject({}) do |acc, data|
|
138
|
+
k,v = data
|
139
|
+
|
140
|
+
if k =~ /^Snapshot(.+?)(-(.+?))?$/
|
141
|
+
current = { $1.to_s.downcase.to_sym => v }
|
142
|
+
|
143
|
+
if $3
|
144
|
+
# This is a child snapshot
|
145
|
+
keys = $3.to_s.split("-").map do |key|
|
146
|
+
key.to_i - 1
|
147
|
+
end
|
148
|
+
final = keys.pop
|
149
|
+
|
150
|
+
location = acc
|
151
|
+
keys.each { |index| location = location[:children][index.to_i] }
|
152
|
+
|
153
|
+
parent = location
|
154
|
+
location = location[:children]
|
155
|
+
location[final] ||= {}
|
156
|
+
location[final].merge!(current)
|
157
|
+
location[final][:parent] = parent
|
158
|
+
location[final][:children] ||= []
|
159
|
+
else
|
160
|
+
acc ||= {}
|
161
|
+
acc.merge!(current)
|
162
|
+
acc[:children] ||= []
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
acc
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Gets the current snapshot.
|
171
|
+
def current_snapshot(info)
|
172
|
+
seen = false
|
173
|
+
uuid = nil
|
174
|
+
VBoxManage.execute("showvminfo", info["UUID"]).split("\n").each do |line|
|
175
|
+
seen = true if line =~ /^Snapshots:/
|
176
|
+
uuid = $2.to_s if seen && line =~ /Name:\s+(.+?)\s+\(UUID:\s+(.+?)\)\s+\*/
|
177
|
+
end
|
178
|
+
|
179
|
+
# The recursive sub-method which finds a snapshot by UUID
|
180
|
+
finder = lambda do |snapshot|
|
181
|
+
return snapshot if snapshot[:uuid] == uuid
|
182
|
+
|
183
|
+
snapshot[:children].find do |child|
|
184
|
+
finder.call(child)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
finder.call(snapshots(info))
|
189
|
+
end
|
109
190
|
end
|
110
191
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Feature: Virtual Machine NAT Engine
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to read and update the NAT engine on a network adapter
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And the forwarded ports are cleared
|
8
|
+
And the adapters are reset
|
9
|
+
And the following adapters are set:
|
10
|
+
| slot | type |
|
11
|
+
| 1 | nat |
|
12
|
+
And the "network_adapters" relationship
|
13
|
+
And the "nat_driver" relationship on collection item "1"
|
14
|
+
|
15
|
+
Scenario: Reading the NAT engine
|
16
|
+
Then the NAT network should exist
|
17
|
+
|
18
|
+
@unsafe
|
19
|
+
Scenario: Reading Forwarded Ports
|
20
|
+
Given I read the adapter in slot "1"
|
21
|
+
And I create a forwarded port named "ssh" from "22" to "2222" via VBoxManage
|
22
|
+
And I reload the VM
|
23
|
+
And I read the adapter in slot "1"
|
24
|
+
Then the forwarded port "ssh" should exist
|
25
|
+
And the forwarded ports should match
|
26
|
+
|
27
|
+
@unsafe
|
28
|
+
Scenario: Creating Forwarded Ports
|
29
|
+
Given I read the adapter in slot "1"
|
30
|
+
When I create a forwarded port named "ssh" from "22" to "2222"
|
31
|
+
And I save the relationship
|
32
|
+
And I reload the VM info
|
33
|
+
Then the forwarded port "ssh" should exist
|
34
|
+
And the forwarded ports should match
|
35
|
+
|
36
|
+
@unsafe
|
37
|
+
Scenario: Updating Forwarded Ports
|
38
|
+
Given I read the adapter in slot "1"
|
39
|
+
And I create a forwarded port named "ssh" from "22" to "2222" via VBoxManage
|
40
|
+
And I reload the VM
|
41
|
+
And I read the adapter in slot "1"
|
42
|
+
When I update the forwarded port named "ssh":
|
43
|
+
| attribute | value |
|
44
|
+
| hostport | 3333 |
|
45
|
+
And I save the relationship
|
46
|
+
And I reload the VM info
|
47
|
+
Then the forwarded ports should match
|
48
|
+
|
49
|
+
@unsafe
|
50
|
+
Scenario: Deleting Forwarded Ports
|
51
|
+
Given I read the adapter in slot "1"
|
52
|
+
And I create a forwarded port named "ssh" from "22" to "2222" via VBoxManage
|
53
|
+
And I reload the VM
|
54
|
+
And I read the adapter in slot "1"
|
55
|
+
When I delete the forwarded port named "ssh"
|
56
|
+
And I reload the VM info
|
57
|
+
Then the forwarded port "ssh" should not exist
|
@@ -4,6 +4,8 @@ Feature: Virtual Machine Shared Folders
|
|
4
4
|
|
5
5
|
Background:
|
6
6
|
Given I find a VM identified by "test_vm_A"
|
7
|
+
And I remove all shared folders
|
8
|
+
And I reload the VM
|
7
9
|
And the "shared_folders" relationship
|
8
10
|
|
9
11
|
@unsafe
|
@@ -18,6 +20,17 @@ Feature: Virtual Machine Shared Folders
|
|
18
20
|
And I add the new record to the relationship
|
19
21
|
And I save the model
|
20
22
|
And I reload the VM info
|
23
|
+
Then the shared folder "bar" should exist
|
24
|
+
Then the shared folder properties should match
|
25
|
+
|
26
|
+
@unsafe
|
27
|
+
Scenario: Updating Shared Folders
|
28
|
+
Given a shared folder "foo" exists
|
29
|
+
When I update the shared folder named "foo":
|
30
|
+
| attribute | value |
|
31
|
+
| host_path | /new_path |
|
32
|
+
And I save the model
|
33
|
+
And I reload the VM info
|
21
34
|
Then the shared folder properties should match
|
22
35
|
|
23
36
|
@unsafe
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Virtual Machine Snapshots
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to manage a VM's snapshots
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And the snapshots are cleared
|
8
|
+
And the "current_snapshot" relationship
|
9
|
+
|
10
|
+
Scenario: Reading the snapshots
|
11
|
+
Given the following snapshot tree is created:
|
12
|
+
| key | children |
|
13
|
+
| foo | bar,baz |
|
14
|
+
| bar | bar1,bar2 |
|
15
|
+
And I reload the VM
|
16
|
+
Then the snapshots should match
|
17
|
+
|
18
|
+
Scenario: Taking a snapshot
|
19
|
+
When I take a snapshot "foo"
|
20
|
+
And I reload the VM info
|
21
|
+
Then the snapshot "foo" should exist
|
22
|
+
|
23
|
+
Scenario: Deleting a snapshot
|
24
|
+
Given the snapshot "foo" is created
|
25
|
+
And I reload the VM
|
26
|
+
When I find the snapshot named "foo"
|
27
|
+
And I destroy the snapshot
|
28
|
+
And I reload the VM info
|
29
|
+
Then the snapshot "foo" should not exist
|
@@ -35,6 +35,13 @@ module VirtualBox
|
|
35
35
|
def reloaded!
|
36
36
|
@_reload = false
|
37
37
|
end
|
38
|
+
|
39
|
+
# Default errors for relationship implementation, since this is
|
40
|
+
# a pretty stable method.
|
41
|
+
def errors_for_relationship(caller, data)
|
42
|
+
return data.errors if data.respond_to?(:errors)
|
43
|
+
nil
|
44
|
+
end
|
38
45
|
end
|
39
46
|
|
40
47
|
# Signals to the class that it should be reloaded. This simply toggles
|
@@ -70,16 +77,16 @@ module VirtualBox
|
|
70
77
|
|
71
78
|
# Returns the errors for a model.
|
72
79
|
def errors
|
73
|
-
|
80
|
+
self.class.relationships.inject(super) do |acc, data|
|
81
|
+
name, options = data
|
74
82
|
|
75
|
-
|
76
|
-
|
77
|
-
|
83
|
+
if options && options[:klass].respond_to?(:errors_for_relationship)
|
84
|
+
errors = options[:klass].errors_for_relationship(self, relationship_data[name])
|
85
|
+
acc.merge!(name => errors) if errors && !errors.empty?
|
86
|
+
end
|
78
87
|
|
79
|
-
|
88
|
+
acc
|
80
89
|
end
|
81
|
-
|
82
|
-
error_hash
|
83
90
|
end
|
84
91
|
|
85
92
|
# Validates the model and relationships.
|
@@ -116,6 +123,15 @@ module VirtualBox
|
|
116
123
|
|
117
124
|
# No longer a new record
|
118
125
|
@new_record = false
|
126
|
+
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
130
|
+
# Saves the model and raises an {Exceptions::ValidationFailedException}
|
131
|
+
# if the model is invalid, instead of returning false.
|
132
|
+
def save!(*args)
|
133
|
+
raise Exceptions::ValidationFailedException.new(errors.inspect) if !save(*args)
|
134
|
+
true
|
119
135
|
end
|
120
136
|
|
121
137
|
# Saves a single attribute of the model. This method on the abstract
|
@@ -206,9 +206,13 @@ module VirtualBox
|
|
206
206
|
# In addition to those two args, any arbitrary args may be tacked on to the
|
207
207
|
# end and they'll be pushed through to the `save_relationship` method.
|
208
208
|
def save_relationships(*args)
|
209
|
-
|
210
|
-
|
209
|
+
# Can't use `all?` here since it short circuits
|
210
|
+
results = self.class.relationships.collect do |data|
|
211
|
+
name, options = data
|
212
|
+
!!save_relationship(name, *args)
|
211
213
|
end
|
214
|
+
|
215
|
+
!results.include?(false)
|
212
216
|
end
|
213
217
|
|
214
218
|
# Saves a single relationship. It is up to the relationship class to
|
@@ -16,11 +16,30 @@ module VirtualBox
|
|
16
16
|
def initialize_mscom
|
17
17
|
require 'win32ole'
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
interface_dir = File.expand_path(File.join(File.dirname(__FILE__), "interface"))
|
20
|
+
Dir[File.join(interface_dir, "*")].each do |f|
|
21
|
+
p "Checking: #{f}"
|
22
|
+
return if File.directory?(f) && initialize_for_version(File.basename(f))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize_for_version(version)
|
27
|
+
COM::Util.set_interface_version(version)
|
21
28
|
|
22
29
|
@virtualbox = COM::Util.versioned_interface(:VirtualBox).new(Implementer::MSCOM, self, WIN32OLE.new("VirtualBox.VirtualBox"))
|
23
30
|
@session = COM::Util.versioned_interface(:Session).new(Implementer::MSCOM, self, WIN32OLE.new("VirtualBox.Session"))
|
31
|
+
|
32
|
+
vb_version = @virtualbox.version
|
33
|
+
|
34
|
+
# Check if they match or not.
|
35
|
+
return false if vb_version.length == version.length
|
36
|
+
(0...(version.length)).each do |i|
|
37
|
+
p "Checking: #{version[i,1]} to #{vb_version[i,1]}"
|
38
|
+
next if version[i,1] == "x"
|
39
|
+
return false if version[i,1] != vb_version[i,1]
|
40
|
+
end
|
41
|
+
|
42
|
+
true
|
24
43
|
end
|
25
44
|
end
|
26
45
|
end
|
@@ -91,8 +91,8 @@ module VirtualBox
|
|
91
91
|
:parent_collection => relation,
|
92
92
|
:name => parts[0],
|
93
93
|
:protocol => COM::Util.versioned_interface(:NATProtocol).index(parts[1]),
|
94
|
-
:guestport => parts[5],
|
95
|
-
:hostport => parts[3]
|
94
|
+
:guestport => parts[5].to_i,
|
95
|
+
:hostport => parts[3].to_i
|
96
96
|
})
|
97
97
|
|
98
98
|
port.existing_record!
|
@@ -136,7 +136,7 @@ module VirtualBox
|
|
136
136
|
def save
|
137
137
|
return true if !new_record? && !changed?
|
138
138
|
raise Exceptions::ValidationFailedException.new(errors) if !valid?
|
139
|
-
destroy if !new_record?
|
139
|
+
destroy(false) if !new_record?
|
140
140
|
|
141
141
|
parent.modify_engine do |nat|
|
142
142
|
nat.add_redirect(name, protocol, "", hostport, "", guestport)
|
@@ -150,13 +150,13 @@ module VirtualBox
|
|
150
150
|
# Destroys the port forwarding mapping.
|
151
151
|
#
|
152
152
|
# @return [Boolean] True if command was successful, false otherwise.
|
153
|
-
def destroy
|
153
|
+
def destroy(update_collection=true)
|
154
154
|
return if new_record?
|
155
155
|
previous_name = name_changed? ? name_was : name
|
156
156
|
parent.modify_engine do |nat|
|
157
157
|
nat.remove_redirect(previous_name)
|
158
158
|
end
|
159
|
-
parent_collection.delete(self, true) if parent_collection
|
159
|
+
parent_collection.delete(self, true) if parent_collection && update_collection
|
160
160
|
new_record!
|
161
161
|
true
|
162
162
|
end
|
@@ -1,19 +1,30 @@
|
|
1
1
|
module VirtualBox
|
2
2
|
# Represents a single NIC (Network Interface Card) of a virtual machine.
|
3
3
|
#
|
4
|
-
#
|
5
|
-
# object is through a {VM}'s `nics` relationship.**
|
4
|
+
# # Create a Network Adapter
|
6
5
|
#
|
7
|
-
#
|
6
|
+
# There is no need to have the ability to create a network adapter,
|
7
|
+
# since when creating a VM from scratch, all eight network adapter
|
8
|
+
# slots are created, but set to `attachment_type` `nil`. Simply
|
9
|
+
# modify the adapter you're interested in and save.
|
8
10
|
#
|
9
|
-
#
|
11
|
+
#
|
12
|
+
# # Editing a Network Adapter
|
13
|
+
#
|
14
|
+
# Network adapters can be modified directly in their relationship to other
|
10
15
|
# virtual machines. When {VM#save} is called, it will also save any
|
11
|
-
# changes to its relationships.
|
16
|
+
# changes to its relationships. Additionally, you may call {#save}
|
17
|
+
# on the relationship itself.
|
12
18
|
#
|
13
19
|
# vm = VirtualBox::VM.find("foo")
|
14
|
-
# vm.
|
20
|
+
# vm.network_adapters[0].macaddress = @new_mac_address
|
15
21
|
# vm.save
|
16
22
|
#
|
23
|
+
# # Destroying a Network Adapter
|
24
|
+
#
|
25
|
+
# Network adapters can not actually be "destroyed" but can be
|
26
|
+
# removed by setting the `attachment_type` to `nil` and saving.
|
27
|
+
#
|
17
28
|
# # Attributes
|
18
29
|
#
|
19
30
|
# Properties of the model are exposed using standard ruby instance
|
@@ -25,12 +36,16 @@ module VirtualBox
|
|
25
36
|
# listed below. If you aren't sure what this means or you can't understand
|
26
37
|
# why the below is listed, please read {Attributable}.
|
27
38
|
#
|
28
|
-
# attribute :
|
29
|
-
# attribute :
|
30
|
-
# attribute :
|
31
|
-
# attribute :
|
32
|
-
# attribute :
|
33
|
-
# attribute :
|
39
|
+
# attribute :slot, :readonly => true
|
40
|
+
# attribute :enabled, :boolean => true
|
41
|
+
# attribute :attachment_type
|
42
|
+
# attribute :adapter_type
|
43
|
+
# attribute :mac_address
|
44
|
+
# attribute :cable_connected, :boolean => true
|
45
|
+
# attribute :nat_network
|
46
|
+
# attribute :internal_network
|
47
|
+
# attribute :host_interface
|
48
|
+
# attribute :interface, :readonly => true, :property => false
|
34
49
|
#
|
35
50
|
class NetworkAdapter < AbstractModel
|
36
51
|
attribute :parent, :readonly => true, :property => false
|
@@ -29,6 +29,14 @@ module VirtualBox
|
|
29
29
|
item
|
30
30
|
end
|
31
31
|
|
32
|
+
# Returns the errors associated with all the items in this
|
33
|
+
# collection
|
34
|
+
def errors
|
35
|
+
collect do |item|
|
36
|
+
item.respond_to?(:errors) ? item.errors : {}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
32
40
|
def <<(item)
|
33
41
|
item.added_to_relationship(self) if item.respond_to?(:added_to_relationship)
|
34
42
|
push(item)
|
@@ -168,7 +168,7 @@ module VirtualBox
|
|
168
168
|
if !new_record?
|
169
169
|
# If its not a new record, any changes will require a new shared
|
170
170
|
# folder to be created, so we first destroy it then recreate it.
|
171
|
-
destroy
|
171
|
+
destroy(false)
|
172
172
|
end
|
173
173
|
|
174
174
|
create
|
@@ -204,14 +204,14 @@ module VirtualBox
|
|
204
204
|
# from the host system. Instead, it simply removes the mapping to the
|
205
205
|
# virtual machine, meaning it will no longer be possible to mount it
|
206
206
|
# from within the virtual machine.
|
207
|
-
def destroy
|
207
|
+
def destroy(update_collection=true)
|
208
208
|
parent.with_open_session do |session|
|
209
209
|
machine = session.machine
|
210
210
|
machine.remove_shared_folder(name)
|
211
211
|
end
|
212
212
|
|
213
213
|
# Remove it from it's parent collection
|
214
|
-
parent_collection.delete(self, true) if parent_collection
|
214
|
+
parent_collection.delete(self, true) if parent_collection && update_collection
|
215
215
|
|
216
216
|
# Mark as a new record so if it is saved again, it will create it
|
217
217
|
new_record!
|
@@ -209,11 +209,11 @@ class RelatableTest < Test::Unit::TestCase
|
|
209
209
|
end
|
210
210
|
|
211
211
|
should "call save_relationship for all relationships" do
|
212
|
-
@model.expects(:save_relationship).with(:foos)
|
213
|
-
@model.expects(:save_relationship).with(:bars)
|
214
|
-
@model.expects(:save_relationship).with(:bazs)
|
215
|
-
@model.expects(:save_relationship).with(:vers)
|
216
|
-
@model.save_relationships
|
212
|
+
@model.expects(:save_relationship).with(:foos).returns(true)
|
213
|
+
@model.expects(:save_relationship).with(:bars).returns(true)
|
214
|
+
@model.expects(:save_relationship).with(:bazs).returns(true)
|
215
|
+
@model.expects(:save_relationship).with(:vers).returns(true)
|
216
|
+
assert @model.save_relationships
|
217
217
|
end
|
218
218
|
|
219
219
|
should "not call save_relationship on non-loaded relations" do
|
@@ -234,8 +234,8 @@ class RelatableTest < Test::Unit::TestCase
|
|
234
234
|
end
|
235
235
|
|
236
236
|
should "call save_relationship on the related class" do
|
237
|
-
Relatee.expects(:save_relationship).with(@model, @model.foos).once
|
238
|
-
@model.save_relationship(:foos)
|
237
|
+
Relatee.expects(:save_relationship).with(@model, @model.foos).once.returns(:r)
|
238
|
+
assert_equal :r, @model.save_relationship(:foos)
|
239
239
|
end
|
240
240
|
|
241
241
|
should "forward parameters through" do
|
@@ -68,6 +68,23 @@ class AbstractModelTest < Test::Unit::TestCase
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
context "errors for relationship default implementation" do
|
72
|
+
setup do
|
73
|
+
@klass = FakeModel
|
74
|
+
end
|
75
|
+
|
76
|
+
should "return the errors on the item" do
|
77
|
+
errors = mock("errors")
|
78
|
+
item = mock("item")
|
79
|
+
item.stubs(:errors).returns(errors)
|
80
|
+
assert_equal errors, @klass.errors_for_relationship(nil, item)
|
81
|
+
end
|
82
|
+
|
83
|
+
should "return nil if the item doesn't respond to errors" do
|
84
|
+
assert_nil @klass.errors_for_relationship(nil, 7)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
71
88
|
context "lazy attributes and relationships" do
|
72
89
|
class LazyModel < VirtualBox::AbstractModel
|
73
90
|
attribute :foo, :lazy => true
|
@@ -285,6 +302,29 @@ class AbstractModelTest < Test::Unit::TestCase
|
|
285
302
|
@model.foo = "foo2"
|
286
303
|
@model.save("YES")
|
287
304
|
end
|
305
|
+
|
306
|
+
should "return true if succeeds" do
|
307
|
+
assert @model.save
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context "save!" do
|
312
|
+
setup do
|
313
|
+
@model = FakeModel.new
|
314
|
+
end
|
315
|
+
|
316
|
+
should "raise an exception if save failed" do
|
317
|
+
args = %W[foo bar baz]
|
318
|
+
@model.expects(:save).with(*args).returns(false)
|
319
|
+
assert_raises(VirtualBox::Exceptions::ValidationFailedException) {
|
320
|
+
@model.save!(*args)
|
321
|
+
}
|
322
|
+
end
|
323
|
+
|
324
|
+
should "not raise an exception if save succeeds" do
|
325
|
+
@model.expects(:save).returns(true)
|
326
|
+
assert_nothing_raised { @model.save! }
|
327
|
+
end
|
288
328
|
end
|
289
329
|
|
290
330
|
context "populating relationships and attributes" do
|
@@ -98,7 +98,7 @@ class NATForwardedPortTest < Test::Unit::TestCase
|
|
98
98
|
|
99
99
|
should "call destroy if not a new record" do
|
100
100
|
@port.name = "diff"
|
101
|
-
@port.expects(:destroy).once
|
101
|
+
@port.expects(:destroy).with(false).once
|
102
102
|
@port.save
|
103
103
|
end
|
104
104
|
end
|
@@ -155,6 +155,12 @@ class NATForwardedPortTest < Test::Unit::TestCase
|
|
155
155
|
assert !@collection.include?(@port)
|
156
156
|
end
|
157
157
|
|
158
|
+
should "not remove itself from collection if specified" do
|
159
|
+
assert @collection.include?(@port)
|
160
|
+
@port.destroy(false)
|
161
|
+
assert @collection.include?(@port)
|
162
|
+
end
|
163
|
+
|
158
164
|
should "remove the redirect from the nat engine interface" do
|
159
165
|
@nat.expects(:remove_redirect).with(@port.name).once
|
160
166
|
@port.destroy
|
@@ -202,8 +208,8 @@ class NATForwardedPortTest < Test::Unit::TestCase
|
|
202
208
|
|
203
209
|
should "have the proper data" do
|
204
210
|
object = @objects.first
|
205
|
-
assert_equal
|
206
|
-
assert_equal
|
211
|
+
assert_equal 22, object.guestport
|
212
|
+
assert_equal 2222, object.hostport
|
207
213
|
assert_equal :tcp, object.protocol
|
208
214
|
assert_equal @objects, object.parent_collection
|
209
215
|
end
|
@@ -40,6 +40,21 @@ class CollectionTest < Test::Unit::TestCase
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
context "errors" do
|
44
|
+
should "return the errors of all the elements" do
|
45
|
+
errors = []
|
46
|
+
3.times do |i|
|
47
|
+
error = "error#{i}"
|
48
|
+
item = mock("item")
|
49
|
+
item.stubs(:errors).returns(error)
|
50
|
+
errors << error
|
51
|
+
@collection << item
|
52
|
+
end
|
53
|
+
|
54
|
+
assert_equal errors, @collection.errors
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
43
58
|
context "element callbacks" do
|
44
59
|
setup do
|
45
60
|
@item = mock("item")
|
@@ -130,7 +130,7 @@ class SharedFolderTest < Test::Unit::TestCase
|
|
130
130
|
assert !@instance.new_record? # sanity
|
131
131
|
|
132
132
|
save_seq = sequence("save_seq")
|
133
|
-
@instance.expects(:destroy).once.in_sequence(save_seq)
|
133
|
+
@instance.expects(:destroy).with(false).once.in_sequence(save_seq)
|
134
134
|
@instance.expects(:create).once.in_sequence(save_seq)
|
135
135
|
|
136
136
|
@instance.save
|
@@ -195,6 +195,12 @@ class SharedFolderTest < Test::Unit::TestCase
|
|
195
195
|
assert !@collection.include?(@instance)
|
196
196
|
end
|
197
197
|
|
198
|
+
should "not remove itself from it's collection if specified" do
|
199
|
+
assert @collection.include?(@instance)
|
200
|
+
@instance.destroy(false)
|
201
|
+
assert @collection.include?(@instance)
|
202
|
+
end
|
203
|
+
|
198
204
|
should "destroy the shared folder on the parent" do
|
199
205
|
destroy_seq = sequence("destroy_seq")
|
200
206
|
@machine.expects(:remove_shared_folder).with(@name).in_sequence(destroy_seq)
|
data/virtualbox.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{virtualbox}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Mitchell Hashimoto"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-07-19}
|
13
13
|
s.description = %q{Create and modify virtual machines in VirtualBox using pure ruby.}
|
14
14
|
s.email = %q{mitchell.hashimoto@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -31,14 +31,17 @@ Gem::Specification.new do |s|
|
|
31
31
|
"features/step_definitions/abstract_model_steps.rb",
|
32
32
|
"features/step_definitions/extra_data_steps.rb",
|
33
33
|
"features/step_definitions/global_steps.rb",
|
34
|
+
"features/step_definitions/nat_engine_steps.rb",
|
34
35
|
"features/step_definitions/network_adapter_steps.rb",
|
35
36
|
"features/step_definitions/shared_folder_steps.rb",
|
37
|
+
"features/step_definitions/snapshot_steps.rb",
|
36
38
|
"features/step_definitions/storage_controller_steps.rb",
|
37
39
|
"features/step_definitions/virtualbox_steps.rb",
|
38
40
|
"features/step_definitions/vm_steps.rb",
|
39
41
|
"features/support/env.rb",
|
40
42
|
"features/support/helpers.rb",
|
41
43
|
"features/support/hooks.rb",
|
44
|
+
"features/support/ordered_hash.rb",
|
42
45
|
"features/support/vboxmanage.rb",
|
43
46
|
"features/version.feature",
|
44
47
|
"features/vm.feature",
|
@@ -46,8 +49,10 @@ Gem::Specification.new do |s|
|
|
46
49
|
"features/vm_cpu.feature",
|
47
50
|
"features/vm_extra_data.feature",
|
48
51
|
"features/vm_hw_virt.feature",
|
52
|
+
"features/vm_nat_engine.feature",
|
49
53
|
"features/vm_network_adapters.feature",
|
50
54
|
"features/vm_shared_folders.feature",
|
55
|
+
"features/vm_snapshots.feature",
|
51
56
|
"features/vm_storage_controllers.feature",
|
52
57
|
"lib/virtualbox.rb",
|
53
58
|
"lib/virtualbox/abstract_model.rb",
|
@@ -298,69 +303,69 @@ Gem::Specification.new do |s|
|
|
298
303
|
s.homepage = %q{http://github.com/mitchellh/virtualbox}
|
299
304
|
s.rdoc_options = ["--charset=UTF-8"]
|
300
305
|
s.require_paths = ["lib"]
|
301
|
-
s.rubygems_version = %q{1.3.
|
306
|
+
s.rubygems_version = %q{1.3.7}
|
302
307
|
s.summary = %q{Create and modify virtual machines in VirtualBox using pure ruby.}
|
303
308
|
s.test_files = [
|
304
|
-
"test/
|
305
|
-
"test/test_helper.rb",
|
306
|
-
"test/virtualbox/network_adapter_test.rb",
|
307
|
-
"test/virtualbox/storage_controller_test.rb",
|
308
|
-
"test/virtualbox/host_test.rb",
|
309
|
-
"test/virtualbox/vm_test.rb",
|
310
|
-
"test/virtualbox/virtual_system_description_test.rb",
|
311
|
-
"test/virtualbox/vrdp_server_test.rb",
|
312
|
-
"test/virtualbox/nat_forwarded_port_test.rb",
|
313
|
-
"test/virtualbox/appliance_test.rb",
|
314
|
-
"test/virtualbox/medium_attachment_test.rb",
|
315
|
-
"test/virtualbox/audio_adapter_test.rb",
|
316
|
-
"test/virtualbox/cpu_test.rb",
|
317
|
-
"test/virtualbox/abstract_model/version_matcher_test.rb",
|
318
|
-
"test/virtualbox/abstract_model/validatable_test.rb",
|
309
|
+
"test/test_helper.rb",
|
319
310
|
"test/virtualbox/abstract_model/attributable_test.rb",
|
320
|
-
"test/virtualbox/abstract_model/relatable_test.rb",
|
321
311
|
"test/virtualbox/abstract_model/dirty_test.rb",
|
322
312
|
"test/virtualbox/abstract_model/interface_attributes_test.rb",
|
323
|
-
"test/virtualbox/
|
324
|
-
"test/virtualbox/
|
325
|
-
"test/virtualbox/
|
326
|
-
"test/virtualbox/snapshot_test.rb",
|
327
|
-
"test/virtualbox/usb_controller_test.rb",
|
328
|
-
"test/virtualbox/forwarded_port_test.rb",
|
329
|
-
"test/virtualbox/dvd_test.rb",
|
330
|
-
"test/virtualbox/hard_drive_test.rb",
|
313
|
+
"test/virtualbox/abstract_model/relatable_test.rb",
|
314
|
+
"test/virtualbox/abstract_model/validatable_test.rb",
|
315
|
+
"test/virtualbox/abstract_model/version_matcher_test.rb",
|
331
316
|
"test/virtualbox/abstract_model_test.rb",
|
332
|
-
"test/virtualbox/
|
333
|
-
"test/virtualbox/
|
334
|
-
"test/virtualbox/
|
335
|
-
"test/virtualbox/com/
|
336
|
-
"test/virtualbox/com/
|
337
|
-
"test/virtualbox/com/
|
317
|
+
"test/virtualbox/appliance_test.rb",
|
318
|
+
"test/virtualbox/audio_adapter_test.rb",
|
319
|
+
"test/virtualbox/bios_test.rb",
|
320
|
+
"test/virtualbox/com/abstract_enum_test.rb",
|
321
|
+
"test/virtualbox/com/abstract_implementer_test.rb",
|
322
|
+
"test/virtualbox/com/abstract_interface_test.rb",
|
338
323
|
"test/virtualbox/com/ffi/interface_test.rb",
|
324
|
+
"test/virtualbox/com/ffi/util_test.rb",
|
339
325
|
"test/virtualbox/com/ffi_interface_test.rb",
|
340
|
-
"test/virtualbox/com/
|
341
|
-
"test/virtualbox/com/
|
326
|
+
"test/virtualbox/com/implementer/base_test.rb",
|
327
|
+
"test/virtualbox/com/implementer/ffi_test.rb",
|
328
|
+
"test/virtualbox/com/implementer/mscom_test.rb",
|
342
329
|
"test/virtualbox/com/mscom_interface_test.rb",
|
343
|
-
"test/virtualbox/com/
|
344
|
-
"test/virtualbox/
|
345
|
-
"test/virtualbox/
|
346
|
-
"test/virtualbox/
|
330
|
+
"test/virtualbox/com/util_test.rb",
|
331
|
+
"test/virtualbox/cpu_test.rb",
|
332
|
+
"test/virtualbox/dhcp_server_test.rb",
|
333
|
+
"test/virtualbox/dvd_test.rb",
|
334
|
+
"test/virtualbox/ext/byte_normalizer_test.rb",
|
335
|
+
"test/virtualbox/ext/platform_test.rb",
|
336
|
+
"test/virtualbox/ext/subclass_listing_test.rb",
|
347
337
|
"test/virtualbox/extra_data_test.rb",
|
348
|
-
"test/virtualbox/
|
338
|
+
"test/virtualbox/forwarded_port_test.rb",
|
339
|
+
"test/virtualbox/global_test.rb",
|
340
|
+
"test/virtualbox/hard_drive_test.rb",
|
341
|
+
"test/virtualbox/host_network_interface_test.rb",
|
342
|
+
"test/virtualbox/host_test.rb",
|
349
343
|
"test/virtualbox/hw_virtualization_test.rb",
|
344
|
+
"test/virtualbox/lib_test.rb",
|
345
|
+
"test/virtualbox/medium_attachment_test.rb",
|
350
346
|
"test/virtualbox/medium_test.rb",
|
347
|
+
"test/virtualbox/nat_engine_test.rb",
|
348
|
+
"test/virtualbox/nat_forwarded_port_test.rb",
|
349
|
+
"test/virtualbox/network_adapter_test.rb",
|
350
|
+
"test/virtualbox/proxies/collection_test.rb",
|
351
|
+
"test/virtualbox/shared_folder_test.rb",
|
352
|
+
"test/virtualbox/snapshot_test.rb",
|
353
|
+
"test/virtualbox/storage_controller_test.rb",
|
354
|
+
"test/virtualbox/system_properties_test.rb",
|
355
|
+
"test/virtualbox/usb_controller_test.rb",
|
351
356
|
"test/virtualbox/usb_device_filter_test.rb",
|
352
|
-
"test/virtualbox/ext/byte_normalizer_test.rb",
|
353
|
-
"test/virtualbox/ext/subclass_listing_test.rb",
|
354
|
-
"test/virtualbox/ext/platform_test.rb",
|
355
357
|
"test/virtualbox/version_test.rb",
|
356
|
-
"test/virtualbox/
|
358
|
+
"test/virtualbox/virtual_system_description_test.rb",
|
359
|
+
"test/virtualbox/vm_test.rb",
|
360
|
+
"test/virtualbox/vrdp_server_test.rb",
|
361
|
+
"test/virtualbox_test.rb"
|
357
362
|
]
|
358
363
|
|
359
364
|
if s.respond_to? :specification_version then
|
360
365
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
361
366
|
s.specification_version = 3
|
362
367
|
|
363
|
-
if Gem::Version.new(Gem::
|
368
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
364
369
|
s.add_runtime_dependency(%q<ffi>, [">= 0.6.3"])
|
365
370
|
else
|
366
371
|
s.add_dependency(%q<ffi>, [">= 0.6.3"])
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: virtualbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 11
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 7
|
8
|
-
-
|
9
|
-
version: 0.7.
|
9
|
+
- 4
|
10
|
+
version: 0.7.4
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Mitchell Hashimoto
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-07-19 00:00:00 -07:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: ffi
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 1
|
27
30
|
segments:
|
28
31
|
- 0
|
29
32
|
- 6
|
@@ -55,14 +58,17 @@ files:
|
|
55
58
|
- features/step_definitions/abstract_model_steps.rb
|
56
59
|
- features/step_definitions/extra_data_steps.rb
|
57
60
|
- features/step_definitions/global_steps.rb
|
61
|
+
- features/step_definitions/nat_engine_steps.rb
|
58
62
|
- features/step_definitions/network_adapter_steps.rb
|
59
63
|
- features/step_definitions/shared_folder_steps.rb
|
64
|
+
- features/step_definitions/snapshot_steps.rb
|
60
65
|
- features/step_definitions/storage_controller_steps.rb
|
61
66
|
- features/step_definitions/virtualbox_steps.rb
|
62
67
|
- features/step_definitions/vm_steps.rb
|
63
68
|
- features/support/env.rb
|
64
69
|
- features/support/helpers.rb
|
65
70
|
- features/support/hooks.rb
|
71
|
+
- features/support/ordered_hash.rb
|
66
72
|
- features/support/vboxmanage.rb
|
67
73
|
- features/version.feature
|
68
74
|
- features/vm.feature
|
@@ -70,8 +76,10 @@ files:
|
|
70
76
|
- features/vm_cpu.feature
|
71
77
|
- features/vm_extra_data.feature
|
72
78
|
- features/vm_hw_virt.feature
|
79
|
+
- features/vm_nat_engine.feature
|
73
80
|
- features/vm_network_adapters.feature
|
74
81
|
- features/vm_shared_folders.feature
|
82
|
+
- features/vm_snapshots.feature
|
75
83
|
- features/vm_storage_controllers.feature
|
76
84
|
- lib/virtualbox.rb
|
77
85
|
- lib/virtualbox/abstract_model.rb
|
@@ -328,77 +336,81 @@ rdoc_options:
|
|
328
336
|
require_paths:
|
329
337
|
- lib
|
330
338
|
required_ruby_version: !ruby/object:Gem::Requirement
|
339
|
+
none: false
|
331
340
|
requirements:
|
332
341
|
- - ">="
|
333
342
|
- !ruby/object:Gem::Version
|
343
|
+
hash: 3
|
334
344
|
segments:
|
335
345
|
- 0
|
336
346
|
version: "0"
|
337
347
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
348
|
+
none: false
|
338
349
|
requirements:
|
339
350
|
- - ">="
|
340
351
|
- !ruby/object:Gem::Version
|
352
|
+
hash: 3
|
341
353
|
segments:
|
342
354
|
- 0
|
343
355
|
version: "0"
|
344
356
|
requirements: []
|
345
357
|
|
346
358
|
rubyforge_project:
|
347
|
-
rubygems_version: 1.3.
|
359
|
+
rubygems_version: 1.3.7
|
348
360
|
signing_key:
|
349
361
|
specification_version: 3
|
350
362
|
summary: Create and modify virtual machines in VirtualBox using pure ruby.
|
351
363
|
test_files:
|
352
|
-
- test/virtualbox_test.rb
|
353
364
|
- test/test_helper.rb
|
354
|
-
- test/virtualbox/network_adapter_test.rb
|
355
|
-
- test/virtualbox/storage_controller_test.rb
|
356
|
-
- test/virtualbox/host_test.rb
|
357
|
-
- test/virtualbox/vm_test.rb
|
358
|
-
- test/virtualbox/virtual_system_description_test.rb
|
359
|
-
- test/virtualbox/vrdp_server_test.rb
|
360
|
-
- test/virtualbox/nat_forwarded_port_test.rb
|
361
|
-
- test/virtualbox/appliance_test.rb
|
362
|
-
- test/virtualbox/medium_attachment_test.rb
|
363
|
-
- test/virtualbox/audio_adapter_test.rb
|
364
|
-
- test/virtualbox/cpu_test.rb
|
365
|
-
- test/virtualbox/abstract_model/version_matcher_test.rb
|
366
|
-
- test/virtualbox/abstract_model/validatable_test.rb
|
367
365
|
- test/virtualbox/abstract_model/attributable_test.rb
|
368
|
-
- test/virtualbox/abstract_model/relatable_test.rb
|
369
366
|
- test/virtualbox/abstract_model/dirty_test.rb
|
370
367
|
- test/virtualbox/abstract_model/interface_attributes_test.rb
|
371
|
-
- test/virtualbox/
|
372
|
-
- test/virtualbox/
|
373
|
-
- test/virtualbox/
|
374
|
-
- test/virtualbox/snapshot_test.rb
|
375
|
-
- test/virtualbox/usb_controller_test.rb
|
376
|
-
- test/virtualbox/forwarded_port_test.rb
|
377
|
-
- test/virtualbox/dvd_test.rb
|
378
|
-
- test/virtualbox/hard_drive_test.rb
|
368
|
+
- test/virtualbox/abstract_model/relatable_test.rb
|
369
|
+
- test/virtualbox/abstract_model/validatable_test.rb
|
370
|
+
- test/virtualbox/abstract_model/version_matcher_test.rb
|
379
371
|
- test/virtualbox/abstract_model_test.rb
|
380
|
-
- test/virtualbox/
|
381
|
-
- test/virtualbox/
|
382
|
-
- test/virtualbox/
|
383
|
-
- test/virtualbox/com/
|
384
|
-
- test/virtualbox/com/
|
385
|
-
- test/virtualbox/com/
|
372
|
+
- test/virtualbox/appliance_test.rb
|
373
|
+
- test/virtualbox/audio_adapter_test.rb
|
374
|
+
- test/virtualbox/bios_test.rb
|
375
|
+
- test/virtualbox/com/abstract_enum_test.rb
|
376
|
+
- test/virtualbox/com/abstract_implementer_test.rb
|
377
|
+
- test/virtualbox/com/abstract_interface_test.rb
|
386
378
|
- test/virtualbox/com/ffi/interface_test.rb
|
379
|
+
- test/virtualbox/com/ffi/util_test.rb
|
387
380
|
- test/virtualbox/com/ffi_interface_test.rb
|
388
|
-
- test/virtualbox/com/
|
389
|
-
- test/virtualbox/com/
|
381
|
+
- test/virtualbox/com/implementer/base_test.rb
|
382
|
+
- test/virtualbox/com/implementer/ffi_test.rb
|
383
|
+
- test/virtualbox/com/implementer/mscom_test.rb
|
390
384
|
- test/virtualbox/com/mscom_interface_test.rb
|
391
|
-
- test/virtualbox/com/
|
392
|
-
- test/virtualbox/
|
393
|
-
- test/virtualbox/
|
394
|
-
- test/virtualbox/
|
385
|
+
- test/virtualbox/com/util_test.rb
|
386
|
+
- test/virtualbox/cpu_test.rb
|
387
|
+
- test/virtualbox/dhcp_server_test.rb
|
388
|
+
- test/virtualbox/dvd_test.rb
|
389
|
+
- test/virtualbox/ext/byte_normalizer_test.rb
|
390
|
+
- test/virtualbox/ext/platform_test.rb
|
391
|
+
- test/virtualbox/ext/subclass_listing_test.rb
|
395
392
|
- test/virtualbox/extra_data_test.rb
|
396
|
-
- test/virtualbox/
|
393
|
+
- test/virtualbox/forwarded_port_test.rb
|
394
|
+
- test/virtualbox/global_test.rb
|
395
|
+
- test/virtualbox/hard_drive_test.rb
|
396
|
+
- test/virtualbox/host_network_interface_test.rb
|
397
|
+
- test/virtualbox/host_test.rb
|
397
398
|
- test/virtualbox/hw_virtualization_test.rb
|
399
|
+
- test/virtualbox/lib_test.rb
|
400
|
+
- test/virtualbox/medium_attachment_test.rb
|
398
401
|
- test/virtualbox/medium_test.rb
|
402
|
+
- test/virtualbox/nat_engine_test.rb
|
403
|
+
- test/virtualbox/nat_forwarded_port_test.rb
|
404
|
+
- test/virtualbox/network_adapter_test.rb
|
405
|
+
- test/virtualbox/proxies/collection_test.rb
|
406
|
+
- test/virtualbox/shared_folder_test.rb
|
407
|
+
- test/virtualbox/snapshot_test.rb
|
408
|
+
- test/virtualbox/storage_controller_test.rb
|
409
|
+
- test/virtualbox/system_properties_test.rb
|
410
|
+
- test/virtualbox/usb_controller_test.rb
|
399
411
|
- test/virtualbox/usb_device_filter_test.rb
|
400
|
-
- test/virtualbox/ext/byte_normalizer_test.rb
|
401
|
-
- test/virtualbox/ext/subclass_listing_test.rb
|
402
|
-
- test/virtualbox/ext/platform_test.rb
|
403
412
|
- test/virtualbox/version_test.rb
|
404
|
-
- test/virtualbox/
|
413
|
+
- test/virtualbox/virtual_system_description_test.rb
|
414
|
+
- test/virtualbox/vm_test.rb
|
415
|
+
- test/virtualbox/vrdp_server_test.rb
|
416
|
+
- test/virtualbox_test.rb
|