vagrant-libvirt 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -9
  3. data/lib/vagrant-libvirt/action/cleanup_on_failure.rb +76 -0
  4. data/lib/vagrant-libvirt/action/create_domain.rb +45 -23
  5. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +5 -1
  6. data/lib/vagrant-libvirt/action/create_networks.rb +13 -0
  7. data/lib/vagrant-libvirt/action/destroy_domain.rb +106 -21
  8. data/lib/vagrant-libvirt/action/destroy_networks.rb +1 -1
  9. data/lib/vagrant-libvirt/action/forward_ports.rb +12 -11
  10. data/lib/vagrant-libvirt/action/wait_till_up.rb +6 -32
  11. data/lib/vagrant-libvirt/action.rb +67 -80
  12. data/lib/vagrant-libvirt/config.rb +45 -33
  13. data/lib/vagrant-libvirt/driver.rb +3 -1
  14. data/lib/vagrant-libvirt/errors.rb +8 -0
  15. data/lib/vagrant-libvirt/templates/domain.xml.erb +223 -226
  16. data/lib/vagrant-libvirt/templates/private_network.xml.erb +4 -1
  17. data/lib/vagrant-libvirt/util/network_util.rb +13 -2
  18. data/lib/vagrant-libvirt/util/resolvers.rb +80 -0
  19. data/lib/vagrant-libvirt/version +1 -1
  20. data/locales/en.yml +13 -0
  21. data/spec/spec_helper.rb +33 -28
  22. data/spec/support/libvirt_context.rb +3 -3
  23. data/spec/unit/action/cleanup_on_failure_spec.rb +131 -0
  24. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +6 -18
  25. data/spec/unit/action/create_domain_spec/custom_disk_settings.xml +43 -0
  26. data/spec/unit/action/create_domain_spec/default_domain.xml +6 -18
  27. data/spec/unit/action/create_domain_spec/two_disk_settings.xml +49 -0
  28. data/spec/unit/action/create_domain_spec.rb +51 -7
  29. data/spec/unit/action/create_domain_volume_spec.rb +5 -3
  30. data/spec/unit/action/destroy_domain_spec/additional_disks_domain.xml +47 -0
  31. data/spec/unit/action/destroy_domain_spec/box_multiple_disks.xml +55 -0
  32. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks.xml +72 -0
  33. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks_no_aliases.xml +67 -0
  34. data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_disks.xml +67 -0
  35. data/spec/unit/action/destroy_domain_spec/cdrom_domain.xml +48 -0
  36. data/spec/unit/action/destroy_domain_spec.rb +134 -30
  37. data/spec/unit/action/forward_ports_spec.rb +10 -2
  38. data/spec/unit/action/prepare_nfs_settings_spec.rb +4 -0
  39. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +6 -18
  40. data/spec/unit/action/start_domain_spec/default.xml +6 -18
  41. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +6 -18
  42. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +6 -18
  43. data/spec/unit/action/start_domain_spec/existing.xml +1 -1
  44. data/spec/unit/action/wait_till_up_spec.rb +2 -42
  45. data/spec/unit/action_spec.rb +2 -0
  46. data/spec/unit/config_spec.rb +85 -26
  47. data/spec/unit/driver_spec.rb +17 -8
  48. data/spec/unit/provider_spec.rb +11 -0
  49. data/spec/unit/templates/domain_all_settings.xml +52 -79
  50. data/spec/unit/templates/domain_cpu_mode_passthrough.xml +39 -0
  51. data/spec/unit/templates/domain_custom_cpu_model.xml +6 -18
  52. data/spec/unit/templates/domain_defaults.xml +6 -18
  53. data/spec/unit/templates/domain_spec.rb +36 -13
  54. data/spec/unit/templates/tpm/version_1.2.xml +6 -18
  55. data/spec/unit/templates/tpm/version_2.0.xml +6 -18
  56. data/spec/unit/util/resolvers_spec.rb +116 -0
  57. metadata +62 -64
@@ -5,25 +5,21 @@
5
5
  <uuid></uuid>
6
6
  <memory></memory>
7
7
  <vcpu cpuset='1-4,^3,6'>1</vcpu>
8
-
9
-
10
8
  <cpu mode='custom'>
11
- <model fallback='allow'>qemu64</model>
12
- <feature name='AAA' policy='required'/>
13
- <topology sockets='1' cores='3' threads='2'/>
9
+ <model fallback='allow'>qemu64</model>
10
+ <feature name='AAA' policy='required'/>
11
+ <topology sockets='1' cores='3' threads='2'/>
14
12
  </cpu>
15
-
16
13
  <numatune>
17
14
  <memory nodeset='1-4,^3,6'/>
18
15
  </numatune>
19
16
  <cputune>
20
17
  <shares>1024</shares>
21
18
  </cputune>
22
-
23
19
  <os>
24
- <type arch='x86_64' machine='pc-compatible'>hvm</type>
25
- <loader readonly='yes' type='rom'>/efi/loader</loader>
26
- <bootmenu enable='yes'/>
20
+ <type arch='x86_64' machine='pc-compatible'>hvm</type>
21
+ <loader readonly='yes' type='rom'>/efi/loader</loader>
22
+ <bootmenu enable='yes'/>
27
23
  <kernel></kernel>
28
24
  <initrd></initrd>
29
25
  <cmdline></cmdline>
@@ -59,15 +55,14 @@
59
55
  <alias name='ua-disk-volume-0'/>
60
56
  <driver name='qemu' type='qcow2' cache='default'/>
61
57
  <source file='/var/lib/libvirt/images/test-disk1.qcow2'/>
62
- <target dev='vdb' bus='virtio'/>
58
+ <target dev='vdc' bus='virtio'/>
63
59
  </disk>
64
60
  <disk type='file' device='disk'>
65
61
  <alias name='ua-disk-volume-1'/>
66
62
  <driver name='qemu' type='qcow2' cache='default' io='threads' copy_on_read='on' discard='unmap' detect_zeroes='on'/>
67
63
  <source file='/var/lib/libvirt/images/test-disk2.qcow2'/>
68
- <target dev='vdc' bus='virtio'/>
64
+ <target dev='vdd' bus='virtio'/>
69
65
  </disk>
70
-
71
66
  <disk type='file' device='cdrom'>
72
67
  <driver name='qemu' type='raw' />
73
68
  <source file=''/>
@@ -80,7 +75,6 @@
80
75
  <target dev='hdb' bus='ide'/>
81
76
  <readonly/>
82
77
  </disk>
83
-
84
78
  <serial type='file'>
85
79
  <source path='/var/log/vm_consoles/machine.log'/>
86
80
  <target port='0'/>
@@ -89,72 +83,52 @@
89
83
  <source path='/var/log/vm_consoles/machine.log'/>
90
84
  <target port='0'/>
91
85
  </console>
92
-
93
- <channel type='unix' >
94
- <target type='virtio'
95
- name="org.qemu.guest_agent.0"
96
- />
97
- </channel>
98
- <channel type='spicevmc' >
99
- <target type='virtio'
100
- name="com.redhat.spice.0"
101
- />
102
- </channel>
103
- <channel type='unix' >
104
- <source
105
- path="/tmp/foo"
106
- />
107
- <target type='guestfwd'
108
- address="192.0.2.42"
109
- port="4242"
110
- />
111
- </channel>
112
-
86
+ <channel type='unix' >
87
+ <target type='virtio' name='org.qemu.guest_agent.0'/>
88
+ </channel>
89
+ <channel type='spicevmc' >
90
+ <target type='virtio' name='com.redhat.spice.0'/>
91
+ </channel>
92
+ <channel type='unix' >
93
+ <source path='/tmp/foo'/>
94
+ <target type='guestfwd' address='192.0.2.42' port='4242'/>
95
+ </channel>
113
96
  <input type='mouse' bus='ps2'/>
114
-
115
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' >
116
- <gl enable='yes' />
117
- </graphics>
118
- <video>
119
- <model type='cirrus' vram='9216' heads='1'>
120
- <acceleration accel3d='yes'/>
121
- </model>
122
- </video>
123
- <rng model='virtio'>
124
- <backend model='random'>/dev/random</backend>
125
- </rng>
126
- <hostdev mode='subsystem' type='pci' managed='yes'>
127
- <source>
128
- <address domain='0x0000'
129
- bus='0x06'
130
- slot='0x12'
131
- function='0x5'/>
132
- </source>
133
- </hostdev>
134
- <hostdev mode='subsystem' type='pci' managed='yes'>
135
- <source>
136
- <address domain='0x0001'
137
- bus='0x03'
138
- slot='0x00'
139
- function='0x0'/>
140
- </source>
141
- </hostdev>
142
- <hostdev mode='subsystem' type='usb'>
143
- <source startupPolicy='mandatory'>
144
- <vendor id='0x1234'/>
145
- <product id='0xabcd'/>
146
- <address bus='1' device='2'/>
147
- </source>
148
- </hostdev>
149
- <redirdev bus='usb' type='tcp'>
150
- </redirdev>
151
- <redirfilter>
152
- <usbdev class='0x0b' vendor='0x08e6' product='0x3437' version='2.00' allow='yes'/>
153
- </redirfilter>
97
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'>
98
+ <gl enable='yes'/>
99
+ </graphics>
100
+ <video>
101
+ <model type='cirrus' vram='16384' heads='1'>
102
+ <acceleration accel3d='yes'/>
103
+ </model>
104
+ </video>
105
+ <rng model='virtio'>
106
+ <backend model='random'>/dev/random</backend>
107
+ </rng>
108
+ <hostdev mode='subsystem' type='pci' managed='yes'>
109
+ <source>
110
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
111
+ </source>
112
+ </hostdev>
113
+ <hostdev mode='subsystem' type='pci' managed='yes'>
114
+ <source>
115
+ <address domain='0x0001' bus='0x03' slot='0x00' function='0x0'/>
116
+ </source>
117
+ </hostdev>
118
+ <hostdev mode='subsystem' type='usb'>
119
+ <source startupPolicy='mandatory'>
120
+ <vendor id='0x1234'/>
121
+ <product id='0xabcd'/>
122
+ <address bus='1' device='2'/>
123
+ </source>
124
+ </hostdev>
125
+ <redirdev bus='usb' type='tcp'>
126
+ </redirdev>
127
+ <redirfilter>
128
+ <usbdev class='0x0b' vendor='0x08e6' product='0x3437' version='2.00' allow='yes'/>
129
+ </redirfilter>
154
130
  <watchdog model='i6300esb' action='reset'/>
155
-
156
- <smartcard mode='passthrough' type='spicevmc'/>
157
-
131
+ <smartcard mode='passthrough' type='spicevmc'/>
158
132
  <tpm model='tpm-tis'>
159
133
  <backend type='passthrough'>
160
134
  <device path='/dev/tpm0'/>
@@ -162,7 +136,6 @@
162
136
  </tpm>
163
137
  <controller type='usb' model='nec-xhci' ports="4" />
164
138
  </devices>
165
-
166
139
  <qemu:commandline>
167
140
  <qemu:arg value='-device'/>
168
141
  <qemu:arg value='dummy-device'/>
@@ -0,0 +1,39 @@
1
+ <domain type='' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
2
+ <name></name>
3
+ <title></title>
4
+ <description></description>
5
+ <uuid></uuid>
6
+ <memory></memory>
7
+ <vcpu>1</vcpu>
8
+ <cpu mode='host-passthrough'>
9
+ <feature policy='optional' name='vmx'/>
10
+ <feature policy='optional' name='svm'/>
11
+ <topology sockets='1' cores='2' threads='1'/>
12
+ </cpu>
13
+ <os>
14
+ <type>hvm</type>
15
+ <kernel></kernel>
16
+ <initrd></initrd>
17
+ <cmdline></cmdline>
18
+ </os>
19
+ <features>
20
+ <acpi/>
21
+ <apic/>
22
+ <pae/>
23
+ </features>
24
+ <clock offset='utc'>
25
+ </clock>
26
+ <devices>
27
+ <serial type='pty'>
28
+ <target port='0'/>
29
+ </serial>
30
+ <console type='pty'>
31
+ <target port='0'/>
32
+ </console>
33
+ <input type='mouse' bus='ps2'/>
34
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
35
+ <video>
36
+ <model type='cirrus' vram='16384' heads='1'/>
37
+ </video>
38
+ </devices>
39
+ </domain>
@@ -5,15 +5,11 @@
5
5
  <uuid></uuid>
6
6
  <memory></memory>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='custom'>
11
- <model fallback='allow'>SandyBridge</model>
9
+ <model fallback='allow'>SandyBridge</model>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel></kernel>
18
14
  <initrd></initrd>
19
15
  <cmdline></cmdline>
@@ -26,24 +22,16 @@
26
22
  <clock offset='utc'>
27
23
  </clock>
28
24
  <devices>
29
-
30
-
31
25
  <serial type='pty'>
32
26
  <target port='0'/>
33
27
  </serial>
34
28
  <console type='pty'>
35
29
  <target port='0'/>
36
30
  </console>
37
-
38
-
39
31
  <input type='mouse' bus='ps2'/>
40
-
41
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
42
- <video>
43
- <model type='cirrus' vram='9216' heads='1'/>
44
- </video>
45
-
46
-
32
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
33
+ <video>
34
+ <model type='cirrus' vram='16384' heads='1'/>
35
+ </video>
47
36
  </devices>
48
-
49
37
  </domain>
@@ -5,15 +5,11 @@
5
5
  <uuid></uuid>
6
6
  <memory></memory>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='host-model'>
11
- <model fallback='allow'></model>
9
+ <model fallback='allow'></model>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel></kernel>
18
14
  <initrd></initrd>
19
15
  <cmdline></cmdline>
@@ -26,24 +22,16 @@
26
22
  <clock offset='utc'>
27
23
  </clock>
28
24
  <devices>
29
-
30
-
31
25
  <serial type='pty'>
32
26
  <target port='0'/>
33
27
  </serial>
34
28
  <console type='pty'>
35
29
  <target port='0'/>
36
30
  </console>
37
-
38
-
39
31
  <input type='mouse' bus='ps2'/>
40
-
41
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
42
- <video>
43
- <model type='cirrus' vram='9216' heads='1'/>
44
- </video>
45
-
46
-
32
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
33
+ <video>
34
+ <model type='cirrus' vram='16384' heads='1'/>
35
+ </video>
47
36
  </devices>
48
-
49
37
  </domain>
@@ -59,13 +59,13 @@ describe 'templates/domain' do
59
59
  domain.disk_device = 'vda'
60
60
  domain.disk_driver(:cache => 'unsafe', :io => 'threads', :copy_on_read => 'on', :discard => 'unmap', :detect_zeroes => 'on')
61
61
  domain.domain_volumes.push({
62
- :dev => 1.vdev.to_s,
62
+ :dev => 'vda',
63
63
  :cache => 'unsafe',
64
64
  :bus => domain.disk_bus,
65
65
  :path => '/var/lib/libvirt/images/test.qcow2'
66
66
  })
67
67
  domain.domain_volumes.push({
68
- :dev => 2.vdev.to_s,
68
+ :dev => 'vdb',
69
69
  :cache => 'unsafe',
70
70
  :bus => domain.disk_bus,
71
71
  :path => '/var/lib/libvirt/images/test2.qcow2'
@@ -118,19 +118,42 @@ describe 'templates/domain' do
118
118
  let(:test_file) { 'domain_all_settings.xml' }
119
119
  it 'renders template' do
120
120
  domain.finalize!
121
+ # resolving is now done during create domain, so need to recreate
122
+ # the same behaviour before calling the template until that
123
+ # is separated out from create domain.
124
+ resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new(prefix=domain.disk_device[0..1])
125
+ resolver.resolve!(domain.domain_volumes.dup.each { |volume| volume[:device] = volume[:dev] })
126
+ resolver.resolve!(domain.disks)
127
+
121
128
  expect(domain.to_xml('domain')).to eq xml_expected
122
129
  end
123
130
  end
124
131
 
125
- context 'when custom cpu model enabled' do
126
- before do
127
- domain.cpu_mode = 'custom'
128
- domain.cpu_model = 'SandyBridge'
132
+ context 'when cpu mode is set' do
133
+ context 'to host-passthrough' do
134
+ before do
135
+ domain.cpu_mode = 'host-passthrough'
136
+ domain.cpu_model = 'SandyBridge'
137
+ domain.cputopology :sockets => '1', :cores => '2', :threads => '1'
138
+ domain.nested = true
139
+ end
140
+ let(:test_file) { 'domain_cpu_mode_passthrough.xml' }
141
+ it 'should allow features and topology and ignore model' do
142
+ domain.finalize!
143
+ expect(domain.to_xml('domain')).to eq xml_expected
144
+ end
129
145
  end
130
- let(:test_file) { 'domain_custom_cpu_model.xml' }
131
- it 'renders template' do
132
- domain.finalize!
133
- expect(domain.to_xml('domain')).to eq xml_expected
146
+
147
+ context 'to custom and model is set' do
148
+ before do
149
+ domain.cpu_mode = 'custom'
150
+ domain.cpu_model = 'SandyBridge'
151
+ end
152
+ let(:test_file) { 'domain_custom_cpu_model.xml' }
153
+ it 'renders template' do
154
+ domain.finalize!
155
+ expect(domain.to_xml('domain')).to eq xml_expected
156
+ end
134
157
  end
135
158
  end
136
159
 
@@ -167,12 +190,12 @@ describe 'templates/domain' do
167
190
  end
168
191
  end
169
192
 
170
- context 'memballon enabled' do
193
+ context 'memballoon enabled' do
171
194
  before do
172
195
  domain.memballoon_enabled = true
173
196
  end
174
197
 
175
- it 'renders with memballon element' do
198
+ it 'renders with memballoon element' do
176
199
  domain.finalize!
177
200
 
178
201
  expect(domain.to_xml('domain')).to match(/<memballoon model='virtio'>/)
@@ -195,7 +218,7 @@ describe 'templates/domain' do
195
218
  end
196
219
  end
197
220
 
198
- context 'memballon disabled' do
221
+ context 'memballoon disabled' do
199
222
  before do
200
223
  domain.memballoon_enabled = false
201
224
  end
@@ -5,15 +5,11 @@
5
5
  <uuid></uuid>
6
6
  <memory></memory>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='host-model'>
11
- <model fallback='allow'></model>
9
+ <model fallback='allow'></model>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel></kernel>
18
14
  <initrd></initrd>
19
15
  <cmdline></cmdline>
@@ -26,29 +22,21 @@
26
22
  <clock offset='utc'>
27
23
  </clock>
28
24
  <devices>
29
-
30
-
31
25
  <serial type='pty'>
32
26
  <target port='0'/>
33
27
  </serial>
34
28
  <console type='pty'>
35
29
  <target port='0'/>
36
30
  </console>
37
-
38
-
39
31
  <input type='mouse' bus='ps2'/>
40
-
41
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
42
- <video>
43
- <model type='cirrus' vram='9216' heads='1'/>
44
- </video>
45
-
46
-
32
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
33
+ <video>
34
+ <model type='cirrus' vram='16384' heads='1'/>
35
+ </video>
47
36
  <tpm model='tpm-tis'>
48
37
  <backend type='passthrough'>
49
38
  <device path='/dev/tpm0'/>
50
39
  </backend>
51
40
  </tpm>
52
41
  </devices>
53
-
54
42
  </domain>
@@ -5,15 +5,11 @@
5
5
  <uuid></uuid>
6
6
  <memory></memory>
7
7
  <vcpu>1</vcpu>
8
-
9
-
10
8
  <cpu mode='host-model'>
11
- <model fallback='allow'></model>
9
+ <model fallback='allow'></model>
12
10
  </cpu>
13
-
14
-
15
11
  <os>
16
- <type>hvm</type>
12
+ <type>hvm</type>
17
13
  <kernel></kernel>
18
14
  <initrd></initrd>
19
15
  <cmdline></cmdline>
@@ -26,28 +22,20 @@
26
22
  <clock offset='utc'>
27
23
  </clock>
28
24
  <devices>
29
-
30
-
31
25
  <serial type='pty'>
32
26
  <target port='0'/>
33
27
  </serial>
34
28
  <console type='pty'>
35
29
  <target port='0'/>
36
30
  </console>
37
-
38
-
39
31
  <input type='mouse' bus='ps2'/>
40
-
41
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
42
- <video>
43
- <model type='cirrus' vram='9216' heads='1'/>
44
- </video>
45
-
46
-
32
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
33
+ <video>
34
+ <model type='cirrus' vram='16384' heads='1'/>
35
+ </video>
47
36
  <tpm model='tpm-crb'>
48
37
  <backend type='emulator' version='2.0'>
49
38
  </backend>
50
39
  </tpm>
51
40
  </devices>
52
-
53
41
  </domain>
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'vagrant-libvirt/util/resolvers'
6
+
7
+ describe VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver do
8
+ subject { described_class.new }
9
+
10
+ def deep_clone_disks(disk_array)
11
+ new_array = []
12
+ disk_array.each do |disk|
13
+ new_array.push disk.dup
14
+ end
15
+
16
+ new_array
17
+ end
18
+
19
+ describe '#resolve!' do
20
+ context 'when using default prefix' do
21
+ [
22
+ [
23
+ [{:name => 'single-disk'}],
24
+ [{:name => 'single-disk', :device => 'vda'}],
25
+ ],
26
+ [
27
+ [{:name => 'disk1'}, {:name => 'disk2'}],
28
+ [{:name => 'disk1', :device => 'vda'}, {:name => 'disk2', :device => 'vdb'}],
29
+ ],
30
+ [
31
+ [{:name => 'disk1'}, {:name => 'disk2', :device => 'vdc'}],
32
+ [{:name => 'disk1', :device => 'vda'}, {:name => 'disk2', :device => 'vdc'}],
33
+ ],
34
+ [
35
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2'}],
36
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2', :device => 'vda'}],
37
+ ],
38
+ ].each do |input_disks, output_disks, options={}|
39
+ opts = {}.merge!(options)
40
+ it "should handle inputs: #{input_disks}" do
41
+ disks = deep_clone_disks(input_disks)
42
+ expect(subject.resolve!(disks)).to eq(output_disks)
43
+ expect(disks).to_not eq(input_disks)
44
+ end
45
+ end
46
+ end
47
+
48
+ context 'when using different default prefix' do
49
+ let(:subject) { described_class.new('sd') }
50
+ [
51
+ [
52
+ [{:name => 'single-disk'}],
53
+ [{:name => 'single-disk', :device => 'sda'}],
54
+ ],
55
+ [
56
+ [{:name => 'disk1'}, {:name => 'disk2'}],
57
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2', :device => 'sdb'}],
58
+ ],
59
+ [
60
+ [{:name => 'disk1'}, {:name => 'disk2', :device => 'vdc'}],
61
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2', :device => 'vdc'}],
62
+ ],
63
+ [
64
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2'}],
65
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2', :device => 'sdb'}],
66
+ ],
67
+ [
68
+ [{:name => 'disk1'}, {:name => 'disk2', :device => 'sda'}],
69
+ [{:name => 'disk1', :device => 'sdb'}, {:name => 'disk2', :device => 'sda'}],
70
+ ],
71
+ ].each do |input_disks, output_disks, options={}|
72
+ opts = {}.merge!(options)
73
+ it "should handle inputs: #{input_disks}" do
74
+ disks = deep_clone_disks(input_disks)
75
+ expect(subject.resolve!(disks)).to eq(output_disks)
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'when using custom prefix' do
81
+ [
82
+ [
83
+ [{:name => 'existing-disk', :device => 'vda'}],
84
+ [{:name => 'single-disk'}],
85
+ [{:name => 'single-disk', :device => 'sda'}],
86
+ {:prefix => 'sd'},
87
+ ],
88
+ [
89
+ [{:name => 'existing-disk', :device => 'vda'}],
90
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2'}],
91
+ [{:name => 'disk1', :device => 'sda'}, {:name => 'disk2', :device => 'sdb'}],
92
+ {:prefix => 'sd'},
93
+ ],
94
+ ].each do |existing, input_disks, output_disks, options={}|
95
+ opts = {}.merge!(options)
96
+ it "should handle inputs: #{input_disks} with opts: #{opts}" do
97
+ disks = deep_clone_disks(input_disks)
98
+ subject.resolve(existing)
99
+ expect(subject.resolve!(disks, opts)).to eq(output_disks)
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ describe '#resolve' do
106
+ let(:input_disks) { [{:name => 'single-disk'}] }
107
+ let(:output_disks) { [{:name => 'single-disk', :device => 'vda'}] }
108
+
109
+ it "should resolve without modifying" do
110
+ disks = deep_clone_disks(input_disks)
111
+ expect(subject.resolve(disks)).to eq(output_disks)
112
+ expect(disks).to_not eq(output_disks)
113
+ expect(disks).to eq(input_disks)
114
+ end
115
+ end
116
+ end