virtualbox 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|