vagrant-libvirt 0.0.45 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +542 -167
- data/lib/vagrant-libvirt/action.rb +2 -2
- data/lib/vagrant-libvirt/action/create_domain.rb +112 -42
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +14 -10
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +8 -5
- data/lib/vagrant-libvirt/action/create_networks.rb +2 -2
- data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
- data/lib/vagrant-libvirt/action/forward_ports.rb +10 -8
- data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
- data/lib/vagrant-libvirt/action/handle_box_image.rb +28 -60
- data/lib/vagrant-libvirt/action/handle_storage_pool.rb +4 -4
- data/lib/vagrant-libvirt/action/package_domain.rb +64 -12
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
- data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +19 -9
- data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
- data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
- data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
- data/lib/vagrant-libvirt/action/start_domain.rb +87 -30
- data/lib/vagrant-libvirt/action/wait_till_up.rb +10 -32
- data/lib/vagrant-libvirt/cap/public_address.rb +16 -0
- data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
- data/lib/vagrant-libvirt/config.rb +294 -42
- data/lib/vagrant-libvirt/driver.rb +49 -34
- data/lib/vagrant-libvirt/errors.rb +5 -5
- data/lib/vagrant-libvirt/plugin.rb +7 -2
- data/lib/vagrant-libvirt/provider.rb +2 -9
- data/lib/vagrant-libvirt/templates/domain.xml.erb +52 -10
- data/lib/vagrant-libvirt/templates/public_interface.xml.erb +5 -1
- data/lib/vagrant-libvirt/util.rb +1 -0
- data/lib/vagrant-libvirt/util/erb_template.rb +6 -7
- data/lib/vagrant-libvirt/util/network_util.rb +6 -1
- data/lib/vagrant-libvirt/util/nfs.rb +17 -0
- data/lib/vagrant-libvirt/util/ui.rb +23 -0
- data/lib/vagrant-libvirt/version +1 -0
- data/lib/vagrant-libvirt/version.rb +72 -1
- data/locales/en.yml +6 -6
- data/spec/spec_helper.rb +28 -2
- data/spec/support/libvirt_context.rb +3 -1
- data/spec/support/sharedcontext.rb +7 -3
- data/spec/unit/action/create_domain_spec.rb +160 -0
- data/spec/unit/action/create_domain_spec/default_system_storage_pool.xml +17 -0
- data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
- data/spec/unit/action/destroy_domain_spec.rb +2 -2
- data/spec/unit/action/set_name_of_domain_spec.rb +3 -3
- data/spec/unit/action/start_domain_spec.rb +231 -0
- data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
- data/spec/unit/action/start_domain_spec/default.xml +48 -0
- data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
- data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
- data/spec/unit/action/wait_till_up_spec.rb +14 -9
- data/spec/unit/config_spec.rb +438 -0
- data/spec/unit/provider_spec.rb +11 -0
- data/spec/unit/templates/domain_all_settings.xml +20 -5
- data/spec/unit/templates/domain_custom_cpu_model.xml +4 -1
- data/spec/unit/templates/domain_defaults.xml +4 -1
- data/spec/unit/templates/domain_spec.rb +92 -4
- data/spec/unit/templates/tpm/version_1.2.xml +54 -0
- data/spec/unit/templates/tpm/version_2.0.xml +53 -0
- metadata +91 -36
- data/.coveralls.yml +0 -1
- data/.github/issue_template.md +0 -37
- data/.gitignore +0 -21
- data/.travis.yml +0 -24
- data/Gemfile +0 -26
- data/Rakefile +0 -8
- data/example_box/README.md +0 -29
- data/example_box/Vagrantfile +0 -60
- data/example_box/metadata.json +0 -5
- data/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb +0 -14
- data/tools/create_box.sh +0 -130
- data/tools/prepare_redhat_for_box.sh +0 -119
- data/vagrant-libvirt.gemspec +0 -51
@@ -23,7 +23,7 @@ module VagrantPlugins
|
|
23
23
|
|
24
24
|
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
|
25
25
|
|
26
|
-
#
|
26
|
+
# Libvirt API doesn't support modifying memory on NUMA enabled CPUs
|
27
27
|
# http://libvirt.org/git/?p=libvirt.git;a=commit;h=d174394105cf00ed266bf729ddf461c21637c736
|
28
28
|
if config.numa_nodes == nil
|
29
29
|
if config.memory.to_i * 1024 != libvirt_domain.max_memory
|
@@ -37,12 +37,16 @@ module VagrantPlugins
|
|
37
37
|
xml_descr = REXML::Document.new descr
|
38
38
|
descr_changed = false
|
39
39
|
|
40
|
+
# For outputting XML for comparison
|
41
|
+
formatter = REXML::Formatters::Pretty.new
|
42
|
+
|
40
43
|
# additional disk bus
|
41
44
|
config.disks.each do |disk|
|
42
45
|
device = disk[:device]
|
43
46
|
bus = disk[:bus]
|
44
47
|
REXML::XPath.each(xml_descr, '/domain/devices/disk[@device="disk"]/target[@dev="' + device + '"]') do |disk_target|
|
45
48
|
next unless disk_target.attributes['bus'] != bus
|
49
|
+
@logger.debug "disk #{device} bus updated from '#{disk_target.attributes['bus']}' to '#{bus}'"
|
46
50
|
descr_changed = true
|
47
51
|
disk_target.attributes['bus'] = bus
|
48
52
|
disk_target.parent.delete_element("#{disk_target.parent.xpath}/address")
|
@@ -52,6 +56,7 @@ module VagrantPlugins
|
|
52
56
|
# disk_bus
|
53
57
|
REXML::XPath.each(xml_descr, '/domain/devices/disk[@device="disk"]/target[@dev="vda"]') do |disk_target|
|
54
58
|
next unless disk_target.attributes['bus'] != config.disk_bus
|
59
|
+
@logger.debug "domain disk bus updated from '#{disk_target.attributes['bus']}' to '#{bus}'"
|
55
60
|
descr_changed = true
|
56
61
|
disk_target.attributes['bus'] = config.disk_bus
|
57
62
|
disk_target.parent.delete_element("#{disk_target.parent.xpath}/address")
|
@@ -61,6 +66,7 @@ module VagrantPlugins
|
|
61
66
|
unless config.nic_model_type.nil?
|
62
67
|
REXML::XPath.each(xml_descr, '/domain/devices/interface/model') do |iface_model|
|
63
68
|
if iface_model.attributes['type'] != config.nic_model_type
|
69
|
+
@logger.debug "network type updated from '#{iface_model.attributes['type']}' to '#{config.nic_model_type}'"
|
64
70
|
descr_changed = true
|
65
71
|
iface_model.attributes['type'] = config.nic_model_type
|
66
72
|
end
|
@@ -68,7 +74,9 @@ module VagrantPlugins
|
|
68
74
|
end
|
69
75
|
|
70
76
|
# vCpu count
|
71
|
-
|
77
|
+
vcpus_count = libvirt_domain.num_vcpus(0)
|
78
|
+
if config.cpus.to_i != vcpus_count
|
79
|
+
@logger.debug "cpu count updated from '#{vcpus_count}' to '#{config.cpus}'"
|
72
80
|
descr_changed = true
|
73
81
|
REXML::XPath.first(xml_descr, '/domain/vcpu').text = config.cpus
|
74
82
|
end
|
@@ -76,11 +84,13 @@ module VagrantPlugins
|
|
76
84
|
# cpu_mode
|
77
85
|
cpu = REXML::XPath.first(xml_descr, '/domain/cpu')
|
78
86
|
if cpu.nil?
|
87
|
+
@logger.debug "cpu_mode updated from not set to '#{config.cpu_mode}'"
|
79
88
|
descr_changed = true
|
80
89
|
cpu = REXML::Element.new('cpu', REXML::XPath.first(xml_descr, '/domain'))
|
81
90
|
cpu.attributes['mode'] = config.cpu_mode
|
82
91
|
else
|
83
92
|
if cpu.attributes['mode'] != config.cpu_mode
|
93
|
+
@logger.debug "cpu_mode updated from '#{cpu.attributes['mode']}' to '#{config.cpu_mode}'"
|
84
94
|
descr_changed = true
|
85
95
|
cpu.attributes['mode'] = config.cpu_mode
|
86
96
|
end
|
@@ -89,16 +99,19 @@ module VagrantPlugins
|
|
89
99
|
if config.cpu_mode != 'host-passthrough'
|
90
100
|
cpu_model = REXML::XPath.first(xml_descr, '/domain/cpu/model')
|
91
101
|
if cpu_model.nil?
|
102
|
+
@logger.debug "cpu_model updated from not set to '#{config.cpu_model}'"
|
92
103
|
descr_changed = true
|
93
104
|
cpu_model = REXML::Element.new('model', REXML::XPath.first(xml_descr, '/domain/cpu'))
|
94
105
|
cpu_model.attributes['fallback'] = 'allow'
|
95
106
|
cpu_model.text = config.cpu_model
|
96
107
|
else
|
97
|
-
if cpu_model.text != config.cpu_model
|
108
|
+
if (cpu_model.text or '').strip != config.cpu_model.strip
|
109
|
+
@logger.debug "cpu_model text updated from #{cpu_model.text} to '#{config.cpu_model}'"
|
98
110
|
descr_changed = true
|
99
111
|
cpu_model.text = config.cpu_model
|
100
112
|
end
|
101
113
|
if cpu_model.attributes['fallback'] != config.cpu_fallback
|
114
|
+
@logger.debug "cpu_model fallback attribute updated from #{cpu_model.attributes['fallback']} to '#{config.cpu_fallback}'"
|
102
115
|
descr_changed = true
|
103
116
|
cpu_model.attributes['fallback'] = config.cpu_fallback
|
104
117
|
end
|
@@ -107,12 +120,14 @@ module VagrantPlugins
|
|
107
120
|
svm_feature = REXML::XPath.first(xml_descr, '/domain/cpu/feature[@name="svm"]')
|
108
121
|
if config.nested
|
109
122
|
if vmx_feature.nil?
|
123
|
+
@logger.debug "nested mode enabled from unset by setting cpu vmx feature"
|
110
124
|
descr_changed = true
|
111
125
|
vmx_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr, '/domain/cpu'))
|
112
126
|
vmx_feature.attributes['policy'] = 'optional'
|
113
127
|
vmx_feature.attributes['name'] = 'vmx'
|
114
128
|
end
|
115
129
|
if svm_feature.nil?
|
130
|
+
@logger.debug "nested mode enabled from unset by setting cpu svm feature"
|
116
131
|
descr_changed = true
|
117
132
|
svm_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr, '/domain/cpu'))
|
118
133
|
svm_feature.attributes['policy'] = 'optional'
|
@@ -120,16 +135,19 @@ module VagrantPlugins
|
|
120
135
|
end
|
121
136
|
else
|
122
137
|
unless vmx_feature.nil?
|
138
|
+
@logger.debug "nested mode disabled for cpu by removing vmx feature"
|
123
139
|
descr_changed = true
|
124
140
|
cpu.delete_element(vmx_feature)
|
125
141
|
end
|
126
142
|
unless svm_feature.nil?
|
143
|
+
@logger.debug "nested mode disabled for cpu by removing svm feature"
|
127
144
|
descr_changed = true
|
128
145
|
cpu.delete_element(svm_feature)
|
129
146
|
end
|
130
147
|
end
|
131
148
|
elsif config.numa_nodes == nil
|
132
149
|
unless cpu.elements.to_a.empty?
|
150
|
+
@logger.debug "switching cpu_mode to host-passthrough and removing emulated cpu features"
|
133
151
|
descr_changed = true
|
134
152
|
cpu.elements.each do |elem|
|
135
153
|
cpu.delete_element(elem)
|
@@ -137,6 +155,34 @@ module VagrantPlugins
|
|
137
155
|
end
|
138
156
|
end
|
139
157
|
|
158
|
+
# Clock
|
159
|
+
clock = REXML::XPath.first(xml_descr, '/domain/clock')
|
160
|
+
if clock.attributes['offset'] != config.clock_offset
|
161
|
+
@logger.debug "clock offset changed"
|
162
|
+
descr_changed = true
|
163
|
+
clock.attributes['offset'] = config.clock_offset
|
164
|
+
end
|
165
|
+
|
166
|
+
# clock timers - because timers can be added/removed, just rebuild and then compare
|
167
|
+
if !config.clock_timers.empty? || clock.has_elements?
|
168
|
+
oldclock = ''
|
169
|
+
formatter.write(REXML::XPath.first(xml_descr, '/domain/clock'), oldclock)
|
170
|
+
clock.delete_element('//timer')
|
171
|
+
config.clock_timers.each do |clock_timer|
|
172
|
+
timer = REXML::Element.new('timer', clock)
|
173
|
+
clock_timer.each do |attr, value|
|
174
|
+
timer.attributes[attr.to_s] = value
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
newclock = ''
|
179
|
+
formatter.write(clock, newclock)
|
180
|
+
unless newclock.eql? oldclock
|
181
|
+
@logger.debug "clock timers config changed"
|
182
|
+
descr_changed = true
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
140
186
|
# Graphics
|
141
187
|
graphics = REXML::XPath.first(xml_descr, '/domain/devices/graphics')
|
142
188
|
if config.graphics_type != 'none'
|
@@ -178,31 +224,31 @@ module VagrantPlugins
|
|
178
224
|
end
|
179
225
|
|
180
226
|
# TPM
|
181
|
-
if config.tpm_path
|
182
|
-
|
227
|
+
if [config.tpm_path, config.tpm_version].any?
|
228
|
+
if config.tpm_path
|
229
|
+
raise Errors::FogCreateServerError, 'The TPM Path must be fully qualified' unless config.tpm_path[0].chr == '/'
|
230
|
+
end
|
183
231
|
|
184
|
-
tpm
|
185
|
-
if
|
232
|
+
# just build the tpm element every time
|
233
|
+
# check at the end if it is different
|
234
|
+
oldtpm = REXML::XPath.first(xml_descr, '/domain/devices/tpm')
|
235
|
+
REXML::XPath.first(xml_descr, '/domain/devices').delete_element("tpm")
|
236
|
+
newtpm = REXML::Element.new('tpm', REXML::XPath.first(xml_descr, '/domain/devices'))
|
237
|
+
|
238
|
+
newtpm.attributes['model'] = config.tpm_model
|
239
|
+
backend = newtpm.add_element('backend')
|
240
|
+
backend.attributes['type'] = config.tpm_type
|
241
|
+
|
242
|
+
case config.tpm_type
|
243
|
+
when 'emulator'
|
244
|
+
backend.attributes['version'] = config.tpm_version
|
245
|
+
when 'passthrough'
|
246
|
+
backend.add_element('device').attributes['path'] = config.tpm_path
|
247
|
+
end
|
248
|
+
|
249
|
+
unless "'#{newtpm}'".eql? "'#{oldtpm}'"
|
250
|
+
@logger.debug "tpm config changed"
|
186
251
|
descr_changed = true
|
187
|
-
tpm = REXML::Element.new('tpm', REXML::XPath.first(xml_descr, '/domain/devices/tpm/model'))
|
188
|
-
tpm.attributes['model'] = config.tpm_model
|
189
|
-
tpm_backend_type = tpm.add_element('backend')
|
190
|
-
tpm_backend_type.attributes['type'] = config.tpm_type
|
191
|
-
tpm_device_path = tpm_backend_type.add_element('device')
|
192
|
-
tpm_device_path.attributes['path'] = config.tpm_path
|
193
|
-
else
|
194
|
-
if tpm.attributes['model'] != config.tpm_model
|
195
|
-
descr_changed = true
|
196
|
-
tpm.attributes['model'] = config.tpm_model
|
197
|
-
end
|
198
|
-
if tpm.elements['backend'].attributes['type'] != config.tpm_type
|
199
|
-
descr_changed = true
|
200
|
-
tpm.elements['backend'].attributes['type'] = config.tpm_type
|
201
|
-
end
|
202
|
-
if tpm.elements['backend'].elements['device'].attributes['path'] != config.tpm_path
|
203
|
-
descr_changed = true
|
204
|
-
tpm.elements['backend'].elements['device'].attributes['path'] = config.tpm_path
|
205
|
-
end
|
206
252
|
end
|
207
253
|
end
|
208
254
|
|
@@ -210,16 +256,21 @@ module VagrantPlugins
|
|
210
256
|
video = REXML::XPath.first(xml_descr, '/domain/devices/video')
|
211
257
|
if !video.nil? && (config.graphics_type == 'none')
|
212
258
|
# graphics_type = none, video devices are removed since there is no possible output
|
259
|
+
@logger.debug "deleting video elements as config.graphics_type is none"
|
213
260
|
descr_changed = true
|
214
261
|
video.parent.delete_element(video)
|
215
262
|
else
|
216
263
|
video_model = REXML::XPath.first(xml_descr, '/domain/devices/video/model')
|
217
264
|
if video_model.nil?
|
265
|
+
@logger.debug "video updated from not set to type '#{config.video_type}' and vram '#{config.video_vram}'"
|
266
|
+
descr_changed = true
|
218
267
|
video_model = REXML::Element.new('model', REXML::XPath.first(xml_descr, '/domain/devices/video'))
|
219
268
|
video_model.attributes['type'] = config.video_type
|
220
269
|
video_model.attributes['vram'] = config.video_vram
|
221
270
|
else
|
222
|
-
if video_model.attributes['type'] != config.video_type || video_model.attributes['vram'] != config.video_vram
|
271
|
+
if video_model.attributes['type'] != config.video_type || video_model.attributes['vram'] != config.video_vram.to_s
|
272
|
+
@logger.debug "video type updated from '#{video_model.attributes['type']}' to '#{config.video_type}'"
|
273
|
+
@logger.debug "video vram updated from '#{video_model.attributes['vram']}' to '#{config.video_vram}'"
|
223
274
|
descr_changed = true
|
224
275
|
video_model.attributes['type'] = config.video_type
|
225
276
|
video_model.attributes['vram'] = config.video_vram
|
@@ -237,11 +288,13 @@ module VagrantPlugins
|
|
237
288
|
if config.dtb
|
238
289
|
dtb = REXML::XPath.first(xml_descr, '/domain/os/dtb')
|
239
290
|
if dtb.nil?
|
291
|
+
@logger.debug "dtb updated from not set to '#{config.dtb}'"
|
240
292
|
descr_changed = true
|
241
293
|
dtb = REXML::Element.new('dtb', REXML::XPath.first(xml_descr, '/domain/os'))
|
242
294
|
dtb.text = config.dtb
|
243
295
|
else
|
244
|
-
if dtb.text != config.dtb
|
296
|
+
if (dtb.text or '') != config.dtb
|
297
|
+
@logger.debug "dtb updated from '#{dtb.text}' to '#{config.dtb}'"
|
245
298
|
descr_changed = true
|
246
299
|
dtb.text = config.dtb
|
247
300
|
end
|
@@ -252,11 +305,13 @@ module VagrantPlugins
|
|
252
305
|
if config.kernel
|
253
306
|
kernel = REXML::XPath.first(xml_descr, '/domain/os/kernel')
|
254
307
|
if kernel.nil?
|
308
|
+
@logger.debug "kernel updated from not set to '#{config.kernel}'"
|
255
309
|
descr_changed = true
|
256
310
|
kernel = REXML::Element.new('kernel', REXML::XPath.first(xml_descr, '/domain/os'))
|
257
311
|
kernel.text = config.kernel
|
258
312
|
else
|
259
|
-
if kernel.text != config.kernel
|
313
|
+
if (kernel.text or '').strip != config.kernel
|
314
|
+
@logger.debug "kernel updated from '#{kernel.text}' to '#{config.kernel}'"
|
260
315
|
descr_changed = true
|
261
316
|
kernel.text = config.kernel
|
262
317
|
end
|
@@ -265,11 +320,13 @@ module VagrantPlugins
|
|
265
320
|
if config.initrd
|
266
321
|
initrd = REXML::XPath.first(xml_descr, '/domain/os/initrd')
|
267
322
|
if initrd.nil?
|
323
|
+
@logger.debug "initrd updated from not set to '#{config.initrd}'"
|
268
324
|
descr_changed = true
|
269
325
|
initrd = REXML::Element.new('initrd', REXML::XPath.first(xml_descr, '/domain/os'))
|
270
326
|
initrd.text = config.initrd
|
271
327
|
else
|
272
|
-
if initrd.text != config.initrd
|
328
|
+
if (initrd.text or '').strip != config.initrd
|
329
|
+
@logger.debug "initrd updated from '#{initrd.text}' to '#{config.initrd}'"
|
273
330
|
descr_changed = true
|
274
331
|
initrd.text = config.initrd
|
275
332
|
end
|
@@ -21,46 +21,26 @@ module VagrantPlugins
|
|
21
21
|
env[:metrics] ||= {}
|
22
22
|
|
23
23
|
# Get domain object
|
24
|
-
domain = env[:machine].provider.driver.get_domain(env[:machine]
|
24
|
+
domain = env[:machine].provider.driver.get_domain(env[:machine])
|
25
25
|
if domain.nil?
|
26
26
|
raise Errors::NoDomainError,
|
27
27
|
error_message: "Domain #{env[:machine].id} not found"
|
28
28
|
end
|
29
29
|
|
30
30
|
# Wait for domain to obtain an ip address. Ip address is searched
|
31
|
-
# from arp table, either
|
31
|
+
# from arp table, either locally or remotely via ssh, if Libvirt
|
32
32
|
# connection was done via ssh.
|
33
33
|
env[:ip_address] = nil
|
34
34
|
@logger.debug("Searching for IP for MAC address: #{domain.mac}")
|
35
35
|
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
return terminate(env) if env[:interrupted]
|
37
|
+
env[:metrics]['instance_ip_time'] = Util::Timer.time do
|
38
|
+
retryable(on: Fog::Errors::TimeoutError, tries: 300) do
|
39
|
+
# just return if interrupted and let the warden call recover
|
40
|
+
return if env[:interrupted]
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
env[:ip_address] = env[:machine].provider.driver.get_ipaddress_system(domain.mac)
|
46
|
-
!env[:ip_address].nil?
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
else
|
51
|
-
env[:metrics]['instance_ip_time'] = Util::Timer.time do
|
52
|
-
retryable(on: Fog::Errors::TimeoutError, tries: 300) do
|
53
|
-
# If we're interrupted don't worry about waiting
|
54
|
-
return terminate(env) if env[:interrupted]
|
55
|
-
|
56
|
-
# Wait for domain to obtain an ip address
|
57
|
-
domain.wait_for(2) do
|
58
|
-
addresses.each_pair do |_type, ip|
|
59
|
-
env[:ip_address] = ip[0] unless ip[0].nil?
|
60
|
-
end
|
61
|
-
!env[:ip_address].nil?
|
62
|
-
end
|
63
|
-
end
|
42
|
+
# Wait for domain to obtain an ip address
|
43
|
+
env[:ip_address] = env[:machine].provider.driver.get_domain_ipaddress(env[:machine], domain)
|
64
44
|
end
|
65
45
|
end
|
66
46
|
|
@@ -84,8 +64,8 @@ module VagrantPlugins
|
|
84
64
|
end
|
85
65
|
end
|
86
66
|
end
|
87
|
-
# if interrupted
|
88
|
-
return
|
67
|
+
# just return if interrupted and let the warden call recover
|
68
|
+
return if env[:interrupted]
|
89
69
|
@logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
|
90
70
|
|
91
71
|
# Booted and ready for use.
|
@@ -95,8 +75,6 @@ module VagrantPlugins
|
|
95
75
|
end
|
96
76
|
|
97
77
|
def recover(env)
|
98
|
-
return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
|
99
|
-
|
100
78
|
# Undo the import
|
101
79
|
terminate(env)
|
102
80
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module ProviderLibvirt
|
3
|
+
module Cap
|
4
|
+
class PublicAddress
|
5
|
+
def self.public_address(machine)
|
6
|
+
# This does not need to be a globally routable address, it
|
7
|
+
# only needs to be accessible from the machine running
|
8
|
+
# Vagrant.
|
9
|
+
ssh_info = machine.ssh_info
|
10
|
+
return nil if !ssh_info
|
11
|
+
ssh_info[:host]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -20,7 +20,7 @@ module VagrantPlugins
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def usable?(machine, _raise_error = false)
|
23
|
-
# bail now if not using
|
23
|
+
# bail now if not using Libvirt since checking version would throw error
|
24
24
|
return false unless machine.provider_name == :libvirt
|
25
25
|
|
26
26
|
# <filesystem/> support in device attach/detach introduced in 1.2.2
|
@@ -30,7 +30,7 @@ module VagrantPlugins
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def prepare(machine, folders, _opts)
|
33
|
-
raise Vagrant::Errors::Error('No
|
33
|
+
raise Vagrant::Errors::Error('No Libvirt connection') if machine.provider.driver.connection.nil?
|
34
34
|
@conn = machine.provider.driver.connection.client
|
35
35
|
|
36
36
|
begin
|
@@ -89,7 +89,7 @@ module VagrantPlugins
|
|
89
89
|
|
90
90
|
def cleanup(machine, _opts)
|
91
91
|
if machine.provider.driver.connection.nil?
|
92
|
-
raise Vagrant::Errors::Error('No
|
92
|
+
raise Vagrant::Errors::Error('No Libvirt connection')
|
93
93
|
end
|
94
94
|
@conn = machine.provider.driver.connection.client
|
95
95
|
begin
|
@@ -20,12 +20,12 @@ module VagrantPlugins
|
|
20
20
|
# A hypervisor name to access via Libvirt.
|
21
21
|
attr_accessor :driver
|
22
22
|
|
23
|
-
# The name of the server, where
|
23
|
+
# The name of the server, where Libvirtd is running.
|
24
24
|
attr_accessor :host
|
25
25
|
|
26
26
|
# If use ssh tunnel to connect to Libvirt.
|
27
27
|
attr_accessor :connect_via_ssh
|
28
|
-
# Path towards the
|
28
|
+
# Path towards the Libvirt socket
|
29
29
|
attr_accessor :socket
|
30
30
|
|
31
31
|
# The username to access Libvirt.
|
@@ -37,11 +37,16 @@ module VagrantPlugins
|
|
37
37
|
# ID SSH key file
|
38
38
|
attr_accessor :id_ssh_key_file
|
39
39
|
|
40
|
+
attr_accessor :proxy_command
|
41
|
+
|
40
42
|
# Libvirt storage pool name, where box image and instance snapshots will
|
41
43
|
# be stored.
|
42
44
|
attr_accessor :storage_pool_name
|
43
45
|
attr_accessor :storage_pool_path
|
44
46
|
|
47
|
+
# Libvirt storage pool where the base image snapshot shall be stored
|
48
|
+
attr_accessor :snapshot_pool_name
|
49
|
+
|
45
50
|
# Turn on to prevent hostname conflicts
|
46
51
|
attr_accessor :random_hostname
|
47
52
|
|
@@ -55,6 +60,7 @@ module VagrantPlugins
|
|
55
60
|
attr_accessor :management_network_autostart
|
56
61
|
attr_accessor :management_network_pci_bus
|
57
62
|
attr_accessor :management_network_pci_slot
|
63
|
+
attr_accessor :management_network_domain
|
58
64
|
|
59
65
|
# System connection information
|
60
66
|
attr_accessor :system_uri
|
@@ -63,18 +69,25 @@ module VagrantPlugins
|
|
63
69
|
attr_accessor :default_prefix
|
64
70
|
|
65
71
|
# Domain specific settings used while creating new domain.
|
72
|
+
attr_accessor :title
|
73
|
+
attr_accessor :description
|
66
74
|
attr_accessor :uuid
|
67
75
|
attr_accessor :memory
|
76
|
+
attr_accessor :nodeset
|
68
77
|
attr_accessor :memory_backing
|
69
78
|
attr_accessor :channel
|
70
79
|
attr_accessor :cpus
|
80
|
+
attr_accessor :cpuset
|
71
81
|
attr_accessor :cpu_mode
|
72
82
|
attr_accessor :cpu_model
|
73
83
|
attr_accessor :cpu_fallback
|
74
84
|
attr_accessor :cpu_features
|
75
85
|
attr_accessor :cpu_topology
|
86
|
+
attr_accessor :shares
|
76
87
|
attr_accessor :features
|
77
88
|
attr_accessor :features_hyperv
|
89
|
+
attr_accessor :clock_offset
|
90
|
+
attr_accessor :clock_timers
|
78
91
|
attr_accessor :numa_nodes
|
79
92
|
attr_accessor :loader
|
80
93
|
attr_accessor :nvram
|
@@ -84,9 +97,10 @@ module VagrantPlugins
|
|
84
97
|
attr_accessor :machine_virtual_size
|
85
98
|
attr_accessor :disk_bus
|
86
99
|
attr_accessor :disk_device
|
100
|
+
attr_accessor :disk_driver_opts
|
87
101
|
attr_accessor :nic_model_type
|
88
102
|
attr_accessor :nested
|
89
|
-
attr_accessor :volume_cache
|
103
|
+
attr_accessor :volume_cache # deprecated, kept for backwards compatibility; use disk_driver
|
90
104
|
attr_accessor :kernel
|
91
105
|
attr_accessor :cmd_line
|
92
106
|
attr_accessor :initrd
|
@@ -108,6 +122,13 @@ module VagrantPlugins
|
|
108
122
|
attr_accessor :tpm_model
|
109
123
|
attr_accessor :tpm_type
|
110
124
|
attr_accessor :tpm_path
|
125
|
+
attr_accessor :tpm_version
|
126
|
+
|
127
|
+
# Configure the memballoon
|
128
|
+
attr_accessor :memballoon_enabled
|
129
|
+
attr_accessor :memballoon_model
|
130
|
+
attr_accessor :memballoon_pci_bus
|
131
|
+
attr_accessor :memballoon_pci_slot
|
111
132
|
|
112
133
|
# Sets the max number of NICs that can be created
|
113
134
|
# Default set to 8. Don't change the default unless you know
|
@@ -158,7 +179,10 @@ module VagrantPlugins
|
|
158
179
|
# Additional qemuargs arguments
|
159
180
|
attr_accessor :qemu_args
|
160
181
|
|
161
|
-
#
|
182
|
+
# Additional qemuenv arguments
|
183
|
+
attr_accessor :qemu_env
|
184
|
+
|
185
|
+
# Use QEMU session instead of system
|
162
186
|
attr_accessor :qemu_use_session
|
163
187
|
|
164
188
|
def initialize
|
@@ -169,7 +193,10 @@ module VagrantPlugins
|
|
169
193
|
@username = UNSET_VALUE
|
170
194
|
@password = UNSET_VALUE
|
171
195
|
@id_ssh_key_file = UNSET_VALUE
|
196
|
+
@socket = UNSET_VALUE
|
197
|
+
@proxy_command = UNSET_VALUE
|
172
198
|
@storage_pool_name = UNSET_VALUE
|
199
|
+
@snapshot_pool_name = UNSET_VALUE
|
173
200
|
@random_hostname = UNSET_VALUE
|
174
201
|
@management_network_device = UNSET_VALUE
|
175
202
|
@management_network_name = UNSET_VALUE
|
@@ -180,22 +207,30 @@ module VagrantPlugins
|
|
180
207
|
@management_network_autostart = UNSET_VALUE
|
181
208
|
@management_network_pci_slot = UNSET_VALUE
|
182
209
|
@management_network_pci_bus = UNSET_VALUE
|
210
|
+
@management_network_domain = UNSET_VALUE
|
183
211
|
|
184
212
|
# System connection information
|
185
213
|
@system_uri = UNSET_VALUE
|
186
214
|
|
187
215
|
# Domain specific settings.
|
216
|
+
@title = UNSET_VALUE
|
217
|
+
@description = UNSET_VALUE
|
188
218
|
@uuid = UNSET_VALUE
|
189
219
|
@memory = UNSET_VALUE
|
220
|
+
@nodeset = UNSET_VALUE
|
190
221
|
@memory_backing = UNSET_VALUE
|
191
222
|
@cpus = UNSET_VALUE
|
223
|
+
@cpuset = UNSET_VALUE
|
192
224
|
@cpu_mode = UNSET_VALUE
|
193
225
|
@cpu_model = UNSET_VALUE
|
194
226
|
@cpu_fallback = UNSET_VALUE
|
195
227
|
@cpu_features = UNSET_VALUE
|
196
228
|
@cpu_topology = UNSET_VALUE
|
229
|
+
@shares = UNSET_VALUE
|
197
230
|
@features = UNSET_VALUE
|
198
231
|
@features_hyperv = UNSET_VALUE
|
232
|
+
@clock_offset = UNSET_VALUE
|
233
|
+
@clock_timers = []
|
199
234
|
@numa_nodes = UNSET_VALUE
|
200
235
|
@loader = UNSET_VALUE
|
201
236
|
@nvram = UNSET_VALUE
|
@@ -204,6 +239,7 @@ module VagrantPlugins
|
|
204
239
|
@machine_virtual_size = UNSET_VALUE
|
205
240
|
@disk_bus = UNSET_VALUE
|
206
241
|
@disk_device = UNSET_VALUE
|
242
|
+
@disk_driver_opts = {}
|
207
243
|
@nic_model_type = UNSET_VALUE
|
208
244
|
@nested = UNSET_VALUE
|
209
245
|
@volume_cache = UNSET_VALUE
|
@@ -226,6 +262,12 @@ module VagrantPlugins
|
|
226
262
|
@tpm_model = UNSET_VALUE
|
227
263
|
@tpm_type = UNSET_VALUE
|
228
264
|
@tpm_path = UNSET_VALUE
|
265
|
+
@tpm_version = UNSET_VALUE
|
266
|
+
|
267
|
+
@memballoon_enabled = UNSET_VALUE
|
268
|
+
@memballoon_model = UNSET_VALUE
|
269
|
+
@memballoon_pci_bus = UNSET_VALUE
|
270
|
+
@memballoon_pci_slot = UNSET_VALUE
|
229
271
|
|
230
272
|
@nic_adapter_count = UNSET_VALUE
|
231
273
|
|
@@ -272,7 +314,12 @@ module VagrantPlugins
|
|
272
314
|
# Attach mgmt network
|
273
315
|
@mgmt_attach = UNSET_VALUE
|
274
316
|
|
275
|
-
|
317
|
+
# Additional QEMU commandline arguments
|
318
|
+
@qemu_args = UNSET_VALUE
|
319
|
+
|
320
|
+
# Additional QEMU commandline environment variables
|
321
|
+
@qemu_env = UNSET_VALUE
|
322
|
+
|
276
323
|
@qemu_use_session = UNSET_VALUE
|
277
324
|
end
|
278
325
|
|
@@ -305,7 +352,7 @@ module VagrantPlugins
|
|
305
352
|
end
|
306
353
|
end
|
307
354
|
|
308
|
-
# is it better to raise our own error, or let
|
355
|
+
# is it better to raise our own error, or let Libvirt cause the exception?
|
309
356
|
raise 'Only four cdroms may be attached at a time'
|
310
357
|
end
|
311
358
|
|
@@ -349,7 +396,29 @@ module VagrantPlugins
|
|
349
396
|
raise 'Feature name AND state must be specified'
|
350
397
|
end
|
351
398
|
|
352
|
-
@features_hyperv = [
|
399
|
+
@features_hyperv = [] if @features_hyperv == UNSET_VALUE
|
400
|
+
|
401
|
+
@features_hyperv.push(name: options[:name],
|
402
|
+
state: options[:state])
|
403
|
+
end
|
404
|
+
|
405
|
+
def clock_timer(options = {})
|
406
|
+
if options[:name].nil?
|
407
|
+
raise 'Clock timer name must be specified'
|
408
|
+
end
|
409
|
+
|
410
|
+
options.each do |key, value|
|
411
|
+
case key
|
412
|
+
when :name, :track, :tickpolicy, :frequency, :mode, :present
|
413
|
+
if value.nil?
|
414
|
+
raise "Value of timer option #{key} is nil"
|
415
|
+
end
|
416
|
+
else
|
417
|
+
raise "Unknown clock timer option: #{key}"
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
@clock_timers.push(options.dup)
|
353
422
|
end
|
354
423
|
|
355
424
|
def cputopology(options = {})
|
@@ -431,7 +500,14 @@ module VagrantPlugins
|
|
431
500
|
|
432
501
|
@pcis = [] if @pcis == UNSET_VALUE
|
433
502
|
|
434
|
-
|
503
|
+
if options[:domain].nil?
|
504
|
+
pci_domain = '0x0000'
|
505
|
+
else
|
506
|
+
pci_domain = options[:domain]
|
507
|
+
end
|
508
|
+
|
509
|
+
@pcis.push(domain: pci_domain,
|
510
|
+
bus: options[:bus],
|
435
511
|
slot: options[:slot],
|
436
512
|
function: options[:function])
|
437
513
|
end
|
@@ -517,6 +593,12 @@ module VagrantPlugins
|
|
517
593
|
@smartcard_dev[:source_service] = options[:source_service] if @smartcard_dev[:type] == 'tcp'
|
518
594
|
end
|
519
595
|
|
596
|
+
# Disk driver options for primary disk
|
597
|
+
def disk_driver(options = {})
|
598
|
+
supported_opts = [:cache, :io, :copy_on_read, :discard, :detect_zeroes]
|
599
|
+
@disk_driver_opts = options.select { |k,_| supported_opts.include? k }
|
600
|
+
end
|
601
|
+
|
520
602
|
# NOTE: this will run twice for each time it's needed- keep it idempotent
|
521
603
|
def storage(storage_type, options = {})
|
522
604
|
if storage_type == :file
|
@@ -570,24 +652,55 @@ module VagrantPlugins
|
|
570
652
|
cache: options[:cache] || 'default',
|
571
653
|
allow_existing: options[:allow_existing],
|
572
654
|
shareable: options[:shareable],
|
573
|
-
serial: options[:serial]
|
655
|
+
serial: options[:serial],
|
656
|
+
io: options[:io],
|
657
|
+
copy_on_read: options[:copy_on_read],
|
658
|
+
discard: options[:discard],
|
659
|
+
detect_zeroes: options[:detect_zeroes],
|
660
|
+
pool: options[:pool], # overrides storage_pool setting for additional disks
|
661
|
+
wwn: options[:wwn],
|
574
662
|
}
|
575
663
|
|
576
664
|
@disks << disk # append
|
577
665
|
end
|
578
666
|
|
579
667
|
def qemuargs(options = {})
|
668
|
+
@qemu_args = [] if @qemu_args == UNSET_VALUE
|
669
|
+
|
580
670
|
@qemu_args << options if options[:value]
|
581
671
|
end
|
582
672
|
|
583
|
-
|
584
|
-
|
585
|
-
|
673
|
+
def qemuenv(options = {})
|
674
|
+
@qemu_env = {} if @qemu_env == UNSET_VALUE
|
675
|
+
|
676
|
+
@qemu_env.merge!(options)
|
677
|
+
end
|
678
|
+
|
679
|
+
def _default_uri
|
680
|
+
# Determine if any settings except driver provided explicitly, if not
|
681
|
+
# and the LIBVIRT_DEFAULT_URI var is set, use that.
|
682
|
+
#
|
683
|
+
# Skipping driver because that may be set on individual boxes rather
|
684
|
+
# than by the user.
|
685
|
+
if [
|
686
|
+
@connect_via_ssh, @host, @username, @password,
|
687
|
+
@id_ssh_key_file, @qemu_use_session, @socket,
|
688
|
+
].none?{ |v| v != UNSET_VALUE }
|
689
|
+
if ENV.fetch('LIBVIRT_DEFAULT_URI', '') != ""
|
690
|
+
@uri = ENV['LIBVIRT_DEFAULT_URI']
|
691
|
+
end
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
695
|
+
# code to generate URI from from either the LIBVIRT_URI environment
|
696
|
+
# variable or a config moved out of the connect action
|
697
|
+
def _generate_uri(qemu_use_session)
|
698
|
+
# builds the Libvirt connection URI from the given driver config
|
586
699
|
# Setup connection uri.
|
587
700
|
uri = @driver.dup
|
588
701
|
virt_path = case uri
|
589
702
|
when 'qemu', 'kvm'
|
590
|
-
|
703
|
+
qemu_use_session ? '/session' : '/system'
|
591
704
|
when 'openvz', 'uml', 'phyp', 'parallels'
|
592
705
|
'/system'
|
593
706
|
when '@en', 'esx'
|
@@ -598,46 +711,67 @@ module VagrantPlugins
|
|
598
711
|
raise "Require specify driver #{uri}"
|
599
712
|
end
|
600
713
|
if uri == 'kvm'
|
601
|
-
uri = 'qemu' # use
|
714
|
+
uri = 'qemu' # use QEMU uri for KVM domain type
|
602
715
|
end
|
603
716
|
|
604
|
-
if
|
717
|
+
# turn on ssh if an ssh key file is explicitly provided
|
718
|
+
if @connect_via_ssh == UNSET_VALUE && @id_ssh_key_file && @id_ssh_key_file != UNSET_VALUE
|
719
|
+
@connect_via_ssh = true
|
720
|
+
end
|
721
|
+
|
722
|
+
params = {}
|
723
|
+
|
724
|
+
if @connect_via_ssh == true
|
725
|
+
finalize_id_ssh_key_file
|
726
|
+
|
605
727
|
uri << '+ssh://'
|
606
|
-
uri << @username + '@' if @username
|
728
|
+
uri << @username + '@' if @username && @username != UNSET_VALUE
|
729
|
+
|
730
|
+
uri << ( @host && @host != UNSET_VALUE ? @host : 'localhost' )
|
607
731
|
|
608
|
-
|
609
|
-
|
610
|
-
else
|
611
|
-
'localhost'
|
612
|
-
end
|
732
|
+
params['no_verify'] = '1'
|
733
|
+
params['keyfile'] = @id_ssh_key_file if @id_ssh_key_file
|
613
734
|
else
|
614
735
|
uri << '://'
|
615
|
-
uri << @host if @host
|
736
|
+
uri << @host if @host && @host != UNSET_VALUE
|
616
737
|
end
|
617
738
|
|
618
739
|
uri << virt_path
|
619
|
-
uri << '?no_verify=1'
|
620
740
|
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
@id_ssh_key_file.prepend("#{`echo ${HOME}`.chomp}/.ssh/") if @id_ssh_key_file !~ /\A\//
|
626
|
-
uri << @id_ssh_key_file
|
627
|
-
end
|
628
|
-
# set path to libvirt socket
|
629
|
-
uri << "\&socket=" + @socket if @socket
|
741
|
+
# set path to Libvirt socket
|
742
|
+
params['socket'] = @socket if @socket
|
743
|
+
|
744
|
+
uri << "?" + params.map{|pair| pair.join('=')}.join('&') if !params.empty?
|
630
745
|
uri
|
631
746
|
end
|
632
747
|
|
748
|
+
def _parse_uri(uri)
|
749
|
+
begin
|
750
|
+
URI.parse(uri)
|
751
|
+
rescue
|
752
|
+
raise "@uri set to invalid uri '#{uri}'"
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
633
756
|
def finalize!
|
757
|
+
_default_uri if @uri == UNSET_VALUE
|
758
|
+
|
759
|
+
# settings which _generate_uri
|
634
760
|
@driver = 'kvm' if @driver == UNSET_VALUE
|
635
|
-
@host = nil if @host == UNSET_VALUE
|
636
|
-
@connect_via_ssh = false if @connect_via_ssh == UNSET_VALUE
|
637
|
-
@username = nil if @username == UNSET_VALUE
|
638
761
|
@password = nil if @password == UNSET_VALUE
|
639
|
-
@
|
762
|
+
@socket = nil if @socket == UNSET_VALUE
|
763
|
+
|
764
|
+
# If uri isn't set then let's build one from various sources.
|
765
|
+
# Default to passing false for qemu_use_session if it's not set.
|
766
|
+
if @uri == UNSET_VALUE
|
767
|
+
@uri = _generate_uri(@qemu_use_session == UNSET_VALUE ? false : @qemu_use_session)
|
768
|
+
end
|
769
|
+
|
770
|
+
finalize_from_uri
|
771
|
+
finalize_proxy_command
|
772
|
+
|
640
773
|
@storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
|
774
|
+
@snapshot_pool_name = @storage_pool_name if @snapshot_pool_name == UNSET_VALUE
|
641
775
|
@storage_pool_path = nil if @storage_pool_path == UNSET_VALUE
|
642
776
|
@random_hostname = false if @random_hostname == UNSET_VALUE
|
643
777
|
@management_network_device = 'virbr0' if @management_network_device == UNSET_VALUE
|
@@ -649,18 +783,18 @@ module VagrantPlugins
|
|
649
783
|
@management_network_autostart = false if @management_network_autostart == UNSET_VALUE
|
650
784
|
@management_network_pci_bus = nil if @management_network_pci_bus == UNSET_VALUE
|
651
785
|
@management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE
|
786
|
+
@management_network_domain = nil if @management_network_domain == UNSET_VALUE
|
652
787
|
@system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE
|
653
788
|
|
654
|
-
@qemu_use_session = false if @qemu_use_session == UNSET_VALUE
|
655
|
-
|
656
|
-
# generate a URI if none is supplied
|
657
|
-
@uri = _generate_uri if @uri == UNSET_VALUE
|
658
|
-
|
659
789
|
# Domain specific settings.
|
790
|
+
@title = '' if @title == UNSET_VALUE
|
791
|
+
@description = '' if @description == UNSET_VALUE
|
660
792
|
@uuid = '' if @uuid == UNSET_VALUE
|
661
793
|
@memory = 512 if @memory == UNSET_VALUE
|
794
|
+
@nodeset = nil if @nodeset == UNSET_VALUE
|
662
795
|
@memory_backing = [] if @memory_backing == UNSET_VALUE
|
663
796
|
@cpus = 1 if @cpus == UNSET_VALUE
|
797
|
+
@cpuset = nil if @cpuset == UNSET_VALUE
|
664
798
|
@cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
|
665
799
|
@cpu_model = if (@cpu_model == UNSET_VALUE) && (@cpu_mode == 'custom')
|
666
800
|
'qemu64'
|
@@ -672,8 +806,11 @@ module VagrantPlugins
|
|
672
806
|
@cpu_topology = {} if @cpu_topology == UNSET_VALUE
|
673
807
|
@cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
|
674
808
|
@cpu_features = [] if @cpu_features == UNSET_VALUE
|
809
|
+
@shares = nil if @shares == UNSET_VALUE
|
675
810
|
@features = ['acpi','apic','pae'] if @features == UNSET_VALUE
|
676
811
|
@features_hyperv = [] if @features_hyperv == UNSET_VALUE
|
812
|
+
@clock_offset = 'utc' if @clock_offset == UNSET_VALUE
|
813
|
+
@clock_timers = [] if @clock_timers == UNSET_VALUE
|
677
814
|
@numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
|
678
815
|
@loader = nil if @loader == UNSET_VALUE
|
679
816
|
@nvram = nil if @nvram == UNSET_VALUE
|
@@ -682,9 +819,10 @@ module VagrantPlugins
|
|
682
819
|
@machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE
|
683
820
|
@disk_bus = 'virtio' if @disk_bus == UNSET_VALUE
|
684
821
|
@disk_device = 'vda' if @disk_device == UNSET_VALUE
|
822
|
+
@disk_driver_opts = {} if @disk_driver_opts == UNSET_VALUE
|
685
823
|
@nic_model_type = nil if @nic_model_type == UNSET_VALUE
|
686
824
|
@nested = false if @nested == UNSET_VALUE
|
687
|
-
@volume_cache =
|
825
|
+
@volume_cache = nil if @volume_cache == UNSET_VALUE
|
688
826
|
@kernel = nil if @kernel == UNSET_VALUE
|
689
827
|
@cmd_line = '' if @cmd_line == UNSET_VALUE
|
690
828
|
@initrd = '' if @initrd == UNSET_VALUE
|
@@ -706,6 +844,11 @@ module VagrantPlugins
|
|
706
844
|
@tpm_model = 'tpm-tis' if @tpm_model == UNSET_VALUE
|
707
845
|
@tpm_type = 'passthrough' if @tpm_type == UNSET_VALUE
|
708
846
|
@tpm_path = nil if @tpm_path == UNSET_VALUE
|
847
|
+
@tpm_version = nil if @tpm_version == UNSET_VALUE
|
848
|
+
@memballoon_enabled = nil if @memballoon_enabled == UNSET_VALUE
|
849
|
+
@memballoon_model = 'virtio' if @memballoon_model == UNSET_VALUE
|
850
|
+
@memballoon_pci_bus = '0x00' if @memballoon_pci_bus == UNSET_VALUE
|
851
|
+
@memballoon_pci_slot = '0x0f' if @memballoon_pci_slot == UNSET_VALUE
|
709
852
|
@nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE
|
710
853
|
@emulator_path = nil if @emulator_path == UNSET_VALUE
|
711
854
|
|
@@ -761,12 +904,24 @@ module VagrantPlugins
|
|
761
904
|
# Attach mgmt network
|
762
905
|
@mgmt_attach = true if @mgmt_attach == UNSET_VALUE
|
763
906
|
|
907
|
+
# Additional QEMU commandline arguments
|
764
908
|
@qemu_args = [] if @qemu_args == UNSET_VALUE
|
909
|
+
|
910
|
+
# Additional QEMU commandline environment variables
|
911
|
+
@qemu_env = {} if @qemu_env == UNSET_VALUE
|
765
912
|
end
|
766
913
|
|
767
914
|
def validate(machine)
|
768
915
|
errors = _detected_errors
|
769
916
|
|
917
|
+
# The @uri and @qemu_use_session should not conflict
|
918
|
+
uri = _parse_uri(@uri)
|
919
|
+
if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
|
920
|
+
if @qemu_use_session != true
|
921
|
+
errors << "the URI and qemu_use_session configuration conflict: uri:'#{@uri}' qemu_use_session:'#{@qemu_use_session}'"
|
922
|
+
end
|
923
|
+
end
|
924
|
+
|
770
925
|
machine.provider_config.disks.each do |disk|
|
771
926
|
if disk[:path] && (disk[:path][0] == '/')
|
772
927
|
errors << "absolute volume paths like '#{disk[:path]}' not yet supported"
|
@@ -785,6 +940,14 @@ module VagrantPlugins
|
|
785
940
|
end
|
786
941
|
end
|
787
942
|
|
943
|
+
if !machine.provider_config.volume_cache.nil? and machine.provider_config.volume_cache != UNSET_VALUE
|
944
|
+
machine.ui.warn("Libvirt Provider: volume_cache is deprecated. Use disk_driver :cache => '#{machine.provider_config.volume_cache}' instead.")
|
945
|
+
|
946
|
+
if !machine.provider_config.disk_driver_opts.empty?
|
947
|
+
machine.ui.warn("Libvirt Provider: volume_cache has no effect when disk_driver is defined.")
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|
788
951
|
{ 'Libvirt Provider' => errors }
|
789
952
|
end
|
790
953
|
|
@@ -797,6 +960,95 @@ module VagrantPlugins
|
|
797
960
|
c = cdroms.dup
|
798
961
|
c += other.cdroms
|
799
962
|
result.cdroms = c
|
963
|
+
|
964
|
+
result.disk_driver_opts = disk_driver_opts.merge(other.disk_driver_opts)
|
965
|
+
|
966
|
+
c = clock_timers.dup
|
967
|
+
c += other.clock_timers
|
968
|
+
result.clock_timers = c
|
969
|
+
|
970
|
+
c = qemu_env != UNSET_VALUE ? qemu_env.dup : {}
|
971
|
+
c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE
|
972
|
+
result.qemu_env = c
|
973
|
+
end
|
974
|
+
end
|
975
|
+
|
976
|
+
private
|
977
|
+
|
978
|
+
def finalize_from_uri
|
979
|
+
# Parse uri to extract individual components
|
980
|
+
uri = _parse_uri(@uri)
|
981
|
+
|
982
|
+
# only set @connect_via_ssh if not explicitly to avoid overriding
|
983
|
+
# and allow an error to occur if the @uri and @connect_via_ssh disagree
|
984
|
+
@connect_via_ssh = uri.scheme.include? "ssh" if @connect_via_ssh == UNSET_VALUE
|
985
|
+
|
986
|
+
# Set qemu_use_session based on the URI if it wasn't set by the user
|
987
|
+
if @qemu_use_session == UNSET_VALUE
|
988
|
+
if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
|
989
|
+
@qemu_use_session = true
|
990
|
+
else
|
991
|
+
@qemu_use_session = false
|
992
|
+
end
|
993
|
+
end
|
994
|
+
|
995
|
+
# Extract host and username values from uri if provided, otherwise nil
|
996
|
+
@host = uri.host
|
997
|
+
@username = uri.user
|
998
|
+
|
999
|
+
finalize_id_ssh_key_file
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
def resolve_ssh_key_file(key_file)
|
1003
|
+
# set ssh key for access to Libvirt host
|
1004
|
+
# if no slash, prepend $HOME/.ssh/
|
1005
|
+
key_file.prepend("#{ENV['HOME']}/.ssh/") if key_file && key_file !~ /\A\//
|
1006
|
+
|
1007
|
+
key_file
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
def finalize_id_ssh_key_file
|
1011
|
+
# resolve based on the following roles
|
1012
|
+
# 1) if @connect_via_ssh is set to true, and id_ssh_key_file not current set,
|
1013
|
+
# set default if the file exists
|
1014
|
+
# 2) if supplied the key name, attempt to expand based on user home
|
1015
|
+
# 3) otherwise set to nil
|
1016
|
+
|
1017
|
+
if @connect_via_ssh == true && @id_ssh_key_file == UNSET_VALUE
|
1018
|
+
# set default if using ssh while allowing a user using nil to disable this
|
1019
|
+
id_ssh_key_file = resolve_ssh_key_file('id_rsa')
|
1020
|
+
id_ssh_key_file = nil if !File.file?(id_ssh_key_file)
|
1021
|
+
elsif @id_ssh_key_file != UNSET_VALUE
|
1022
|
+
id_ssh_key_file = resolve_ssh_key_file(@id_ssh_key_file)
|
1023
|
+
else
|
1024
|
+
id_ssh_key_file = nil
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
@id_ssh_key_file = id_ssh_key_file
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
def finalize_proxy_command
|
1031
|
+
if @connect_via_ssh
|
1032
|
+
if @proxy_command == UNSET_VALUE
|
1033
|
+
proxy_command = "ssh '#{@host}' "
|
1034
|
+
proxy_command << "-l '#{@username}' " if @username
|
1035
|
+
proxy_command << "-i '#{@id_ssh_key_file}' " if @id_ssh_key_file
|
1036
|
+
proxy_command << '-W %h:%p'
|
1037
|
+
else
|
1038
|
+
inputs = { host: @host }
|
1039
|
+
inputs[:username] = @username if @username
|
1040
|
+
inputs[:id_ssh_key_file] = @id_ssh_key_file if @id_ssh_key_file
|
1041
|
+
|
1042
|
+
proxy_command = @proxy_command
|
1043
|
+
# avoid needing to escape '%' symbols
|
1044
|
+
inputs.each do |key, value|
|
1045
|
+
proxy_command.gsub!("{#{key}}", value)
|
1046
|
+
end
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
@proxy_command = proxy_command
|
1050
|
+
else
|
1051
|
+
@proxy_command = nil
|
800
1052
|
end
|
801
1053
|
end
|
802
1054
|
end
|