vagrant-libvirt 0.0.32 → 0.0.33
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/.travis.yml +1 -0
- data/Gemfile +4 -0
- data/README.md +146 -22
- data/lib/vagrant-libvirt/action/create_domain.rb +35 -0
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +1 -0
- data/lib/vagrant-libvirt/action/create_networks.rb +2 -0
- data/lib/vagrant-libvirt/action/forward_ports.rb +2 -2
- data/lib/vagrant-libvirt/action/handle_box_image.rb +3 -1
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +9 -9
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -4
- data/lib/vagrant-libvirt/action/start_domain.rb +136 -30
- data/lib/vagrant-libvirt/action/wait_till_up.rb +22 -14
- data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +7 -1
- data/lib/vagrant-libvirt/cap/synced_folder.rb +6 -3
- data/lib/vagrant-libvirt/config.rb +109 -0
- data/lib/vagrant-libvirt/plugin.rb +3 -0
- data/lib/vagrant-libvirt/templates/domain.xml.erb +57 -7
- data/lib/vagrant-libvirt/templates/interface.xml.erb +5 -1
- data/lib/vagrant-libvirt/templates/private_network.xml.erb +1 -1
- data/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb +6 -0
- data/lib/vagrant-libvirt/util/network_util.rb +2 -0
- data/lib/vagrant-libvirt/version.rb +1 -1
- data/locales/en.yml +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/libvirt_context.rb +28 -0
- data/spec/support/sharedcontext.rb +34 -0
- data/spec/{vagrant-libvirt → unit}/action/set_name_of_domain_spec.rb +0 -0
- data/spec/unit/action/wait_till_up_spec.rb +128 -0
- data/tools/create_box.sh +3 -1
- data/vagrant-libvirt.gemspec +4 -4
- metadata +21 -15
@@ -67,7 +67,9 @@ module VagrantPlugins
|
|
67
67
|
env[:ui].info(I18n.t('vagrant_libvirt.uploading_volume'))
|
68
68
|
|
69
69
|
# Create new volume in storage pool
|
70
|
-
|
70
|
+
unless File.exists?(box_image_file)
|
71
|
+
raise Vagrant::Errors::BoxNotFound.new(name: env[:machine].box.name)
|
72
|
+
end
|
71
73
|
box_image_size = File.size(box_image_file) # B
|
72
74
|
message = "Creating volume #{env[:box_volume_name]}"
|
73
75
|
message << " in storage pool #{config.storage_pool_name}."
|
@@ -40,15 +40,15 @@ module VagrantPlugins
|
|
40
40
|
# @param [Machine] machine
|
41
41
|
# @return [String]
|
42
42
|
def read_host_ip(ip)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
UDPSocket.open do |s|
|
44
|
+
if(ip.kind_of?(Array))
|
45
|
+
s.connect(ip.last, 1)
|
46
|
+
else
|
47
|
+
s.connect(ip, 1)
|
48
|
+
end
|
49
|
+
s.addr.last
|
50
|
+
end
|
48
51
|
end
|
49
|
-
s.addr.last
|
50
|
-
end
|
51
|
-
end
|
52
52
|
# Returns the IP address of the guest
|
53
53
|
#
|
54
54
|
# @param [Machine] machine
|
@@ -65,7 +65,7 @@ module VagrantPlugins
|
|
65
65
|
result << data if type == :stdout
|
66
66
|
end
|
67
67
|
|
68
|
-
ips = result.chomp.split("\n")
|
68
|
+
ips = result.chomp.split("\n").uniq
|
69
69
|
@logger.info("guest IPs: #{ips.join(', ')}")
|
70
70
|
ips.each do |ip|
|
71
71
|
next if ip == ssh_host
|
@@ -46,13 +46,15 @@ module VagrantPlugins
|
|
46
46
|
config = env[:machine].provider_config
|
47
47
|
domain_name =
|
48
48
|
if config.default_prefix.nil?
|
49
|
-
env[:root_path].basename.to_s.dup
|
49
|
+
env[:root_path].basename.to_s.dup.concat("_")
|
50
|
+
elsif config.default_prefix.empty?
|
51
|
+
# don't have any prefix, not even "_"
|
52
|
+
""
|
50
53
|
else
|
51
|
-
config.default_prefix.to_s
|
54
|
+
config.default_prefix.to_s.concat("_")
|
52
55
|
end
|
53
|
-
domain_name << '_'
|
54
56
|
domain_name << env[:machine].name.to_s
|
55
|
-
domain_name.gsub!(/[^-a-z0-9_]/i, '')
|
57
|
+
domain_name.gsub!(/[^-a-z0-9_\.]/i, '')
|
56
58
|
domain_name << "_#{Time.now.utc.to_i}_#{SecureRandom.hex(10)}" if config.random_hostname
|
57
59
|
domain_name
|
58
60
|
end
|
@@ -23,8 +23,8 @@ module VagrantPlugins
|
|
23
23
|
|
24
24
|
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
|
25
25
|
|
26
|
-
if config.memory*1024 != libvirt_domain.max_memory
|
27
|
-
libvirt_domain.max_memory = config.memory*1024
|
26
|
+
if config.memory.to_i*1024 != libvirt_domain.max_memory
|
27
|
+
libvirt_domain.max_memory = config.memory.to_i*1024
|
28
28
|
libvirt_domain.memory = libvirt_domain.max_memory
|
29
29
|
end
|
30
30
|
begin
|
@@ -88,7 +88,16 @@ module VagrantPlugins
|
|
88
88
|
descr_changed = true
|
89
89
|
cpu_model = REXML::Element.new('model', REXML::XPath.first(xml_descr,'/domain/cpu'))
|
90
90
|
cpu_model.attributes['fallback'] = 'allow'
|
91
|
-
cpu_model.text =
|
91
|
+
cpu_model.text = config.cpu_model
|
92
|
+
else
|
93
|
+
if cpu_model.text != config.cpu_model
|
94
|
+
descr_changed = true
|
95
|
+
cpu_model.text = config.cpu_model
|
96
|
+
end
|
97
|
+
if cpu_model.attributes['fallback'] != config.cpu_fallback
|
98
|
+
descr_changed = true
|
99
|
+
cpu_model.attributes['fallback'] = config.cpu_fallback
|
100
|
+
end
|
92
101
|
end
|
93
102
|
vmx_feature = REXML::XPath.first(xml_descr,'/domain/cpu/feature[@name="vmx"]')
|
94
103
|
svm_feature = REXML::XPath.first(xml_descr,'/domain/cpu/feature[@name="svm"]')
|
@@ -126,42 +135,137 @@ module VagrantPlugins
|
|
126
135
|
|
127
136
|
# Graphics
|
128
137
|
graphics = REXML::XPath.first(xml_descr,'/domain/devices/graphics')
|
129
|
-
if
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
138
|
+
if config.graphics_type != 'none'
|
139
|
+
if graphics.nil?
|
140
|
+
descr_changed = true
|
141
|
+
graphics = REXML::Element.new('graphics', REXML::XPath.first(xml_descr,'/domain/devices'))
|
142
|
+
end
|
143
|
+
if graphics.attributes['type'] != config.graphics_type
|
144
|
+
descr_changed = true
|
145
|
+
graphics.attributes['type'] = config.graphics_type
|
146
|
+
end
|
147
|
+
if graphics.attributes['listen'] != config.graphics_ip
|
148
|
+
descr_changed = true
|
149
|
+
graphics.attributes['listen'] = config.graphics_ip
|
150
|
+
graphics.delete_element('//listen')
|
151
|
+
end
|
152
|
+
if graphics.attributes['autoport'] != config.graphics_autoport
|
153
|
+
descr_changed = true
|
154
|
+
graphics.attributes['autoport'] = config.graphics_autoport
|
155
|
+
if config.graphics_autoport == 'no'
|
156
|
+
graphics.attributes['port'] = config.graphics_port
|
157
|
+
end
|
158
|
+
end
|
159
|
+
if graphics.attributes['keymap'] != config.keymap
|
160
|
+
descr_changed = true
|
161
|
+
graphics.attributes['keymap'] = config.keymap
|
162
|
+
end
|
163
|
+
if graphics.attributes['passwd'] != config.graphics_passwd
|
164
|
+
descr_changed = true
|
165
|
+
if config.graphics_passwd.nil?
|
166
|
+
graphics.attributes.delete 'passwd'
|
167
|
+
else
|
168
|
+
graphics.attributes['passwd'] = config.graphics_passwd
|
169
|
+
end
|
170
|
+
end
|
171
|
+
else
|
172
|
+
# graphics_type = none, remove entire element
|
173
|
+
if !graphics.nil?
|
174
|
+
graphics.parent.delete_element(graphics)
|
175
|
+
end
|
137
176
|
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
177
|
+
|
178
|
+
#TPM
|
179
|
+
if config.tpm_path
|
180
|
+
raise Errors::FogCreateServerError, "The TPM Path must be fully qualified" unless config.tpm_path[0].chr == '/'
|
181
|
+
|
182
|
+
tpm = REXML::XPath.first(xml_descr,'/domain/devices/tpm')
|
183
|
+
if tpm.nil?
|
184
|
+
descr_changed = true
|
185
|
+
tpm = REXML::Element.new('tpm', REXML::XPath.first(xml_descr,'/domain/devices/tpm/model'))
|
186
|
+
tpm.attributes['model'] = config.tpm_model
|
187
|
+
tpm_backend_type = tpm.add_element('backend')
|
188
|
+
tpm_backend_type.attributes['type'] = config.tpm_type
|
189
|
+
tpm_device_path = tpm_backend_type.add_element('device')
|
190
|
+
tpm_device_path.attributes['path'] = config.tpm_path
|
191
|
+
else
|
192
|
+
if tpm.attributes['model'] != config.tpm_model
|
193
|
+
descr_changed = true
|
194
|
+
tpm.attributes['model'] = config.tpm_model
|
195
|
+
end
|
196
|
+
if tpm.elements['backend'].attributes['type'] != config.tpm_type
|
197
|
+
descr_changed = true
|
198
|
+
tpm.elements['backend'].attributes['type'] = config.tpm_type
|
199
|
+
end
|
200
|
+
if tpm.elements['backend'].elements['device'].attributes['path'] != config.tpm_path
|
201
|
+
descr_changed = true
|
202
|
+
tpm.elements['backend'].elements['device'].attributes['path'] = config.tpm_path
|
203
|
+
end
|
143
204
|
end
|
144
205
|
end
|
145
|
-
|
206
|
+
|
207
|
+
# Video device
|
208
|
+
video = REXML::XPath.first(xml_descr,'/domain/devices/video')
|
209
|
+
if !video.nil? and config.graphics_type == 'none'
|
210
|
+
# graphics_type = none, video devices are removed since there is no possible output
|
146
211
|
descr_changed = true
|
147
|
-
|
212
|
+
video.parent.delete_element(video)
|
213
|
+
else
|
214
|
+
video_model = REXML::XPath.first(xml_descr,'/domain/devices/video/model')
|
215
|
+
if video_model.nil?
|
216
|
+
video_model = REXML::Element.new('model', REXML::XPath.first(xml_descr,'/domain/devices/video'))
|
217
|
+
video_model.attributes['type'] = config.video_type
|
218
|
+
video_model.attributes['vram'] = config.video_vram
|
219
|
+
else
|
220
|
+
if video_model.attributes['type'] != config.video_type || video_model.attributes['vram'] != config.video_vram
|
221
|
+
descr_changed = true
|
222
|
+
video_model.attributes['type'] = config.video_type
|
223
|
+
video_model.attributes['vram'] = config.video_vram
|
224
|
+
end
|
225
|
+
end
|
148
226
|
end
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
227
|
+
|
228
|
+
# dtb
|
229
|
+
if config.dtb
|
230
|
+
dtb = REXML::XPath.first(xml_descr,'/domain/os/dtb')
|
231
|
+
if dtb.nil?
|
232
|
+
descr_changed = true
|
233
|
+
dtb = REXML::Element.new('dtb', REXML::XPath.first(xml_descr,'/domain/os'))
|
234
|
+
dtb.text = config.dtb
|
153
235
|
else
|
154
|
-
|
236
|
+
if dtb.text != config.dtb
|
237
|
+
descr_changed = true
|
238
|
+
dtb.text = config.dtb
|
239
|
+
end
|
155
240
|
end
|
156
241
|
end
|
157
242
|
|
158
|
-
#
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
243
|
+
# kernel and initrd
|
244
|
+
if config.kernel
|
245
|
+
kernel= REXML::XPath.first(xml_descr,'/domain/os/kernel')
|
246
|
+
if kernel.nil?
|
247
|
+
descr_changed = true
|
248
|
+
kernel = REXML::Element.new('kernel', REXML::XPath.first(xml_descr,'/domain/os'))
|
249
|
+
kernel.text = config.kernel
|
250
|
+
else
|
251
|
+
if kernel.text != config.kernel
|
252
|
+
descr_changed = true
|
253
|
+
kernel.text = config.kernel
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
if config.initrd
|
258
|
+
initrd = REXML::XPath.first(xml_descr,'/domain/os/initrd')
|
259
|
+
if initrd.nil?
|
260
|
+
descr_changed = true
|
261
|
+
initrd = REXML::Element.new('initrd', REXML::XPath.first(xml_descr,'/domain/os'))
|
262
|
+
initrd.text = config.initrd
|
263
|
+
else
|
264
|
+
if initrd.text != config.initrd
|
265
|
+
descr_changed = true
|
266
|
+
initrd.text = config.initrd
|
267
|
+
end
|
268
|
+
end
|
165
269
|
end
|
166
270
|
|
167
271
|
# Apply
|
@@ -179,6 +283,8 @@ module VagrantPlugins
|
|
179
283
|
rescue => e
|
180
284
|
env[:ui].error("Error when updating domain settings: #{e.message}")
|
181
285
|
end
|
286
|
+
# Autostart with host if enabled in Vagrantfile
|
287
|
+
libvirt_domain.autostart = config.autostart
|
182
288
|
# Actually start the domain
|
183
289
|
domain.start
|
184
290
|
rescue => e
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'log4r'
|
2
|
+
require 'vagrant-libvirt/errors'
|
2
3
|
require 'vagrant-libvirt/util/timer'
|
3
4
|
require 'vagrant/util/retryable'
|
4
5
|
|
@@ -21,18 +22,22 @@ module VagrantPlugins
|
|
21
22
|
env[:metrics] ||= {}
|
22
23
|
|
23
24
|
# Get domain object
|
24
|
-
domain = env[:machine].provider.driver.
|
25
|
-
|
25
|
+
domain = env[:machine].provider.driver.get_domain(env[:machine].id.to_s)
|
26
|
+
if domain == nil
|
27
|
+
raise Errors::NoDomainError,
|
28
|
+
:error_message => "Domain #{env[:machine].id} not found"
|
29
|
+
end
|
26
30
|
|
27
31
|
# Wait for domain to obtain an ip address. Ip address is searched
|
28
32
|
# from arp table, either localy or remotely via ssh, if libvirt
|
29
33
|
# connection was done via ssh.
|
30
34
|
env[:ip_address] = nil
|
31
35
|
env[:metrics]["instance_ip_time"] = Util::Timer.time do
|
36
|
+
@logger.debug("Searching for IP for MAC address: #{domain.mac}")
|
32
37
|
env[:ui].info(I18n.t("vagrant_libvirt.waiting_for_ip"))
|
33
38
|
retryable(:on => Fog::Errors::TimeoutError, :tries => 300) do
|
34
39
|
# If we're interrupted don't worry about waiting
|
35
|
-
|
40
|
+
return terminate(env) if env[:interrupted]
|
36
41
|
|
37
42
|
# Wait for domain to obtain an ip address
|
38
43
|
domain.wait_for(2) {
|
@@ -43,7 +48,6 @@ module VagrantPlugins
|
|
43
48
|
}
|
44
49
|
end
|
45
50
|
end
|
46
|
-
terminate(env) if env[:interrupted]
|
47
51
|
@logger.info("Got IP address #{env[:ip_address]}")
|
48
52
|
@logger.info("Time for getting IP: #{env[:metrics]["instance_ip_time"]}")
|
49
53
|
|
@@ -64,7 +68,8 @@ module VagrantPlugins
|
|
64
68
|
end
|
65
69
|
end
|
66
70
|
end
|
67
|
-
|
71
|
+
# if interrupted above, just terminate immediately
|
72
|
+
return terminate(env) if env[:interrupted]
|
68
73
|
@logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
|
69
74
|
|
70
75
|
# Booted and ready for use.
|
@@ -76,18 +81,21 @@ module VagrantPlugins
|
|
76
81
|
def recover(env)
|
77
82
|
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
78
83
|
|
79
|
-
|
80
|
-
|
81
|
-
terminate(env)
|
82
|
-
end
|
84
|
+
# Undo the import
|
85
|
+
terminate(env)
|
83
86
|
end
|
84
87
|
|
85
88
|
def terminate(env)
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
89
|
+
if env[:machine].provider.state.id != :not_created
|
90
|
+
# If we're not supposed to destroy on error then just return
|
91
|
+
return if !env[:destroy_on_error]
|
92
|
+
|
93
|
+
destroy_env = env.dup
|
94
|
+
destroy_env.delete(:interrupted)
|
95
|
+
destroy_env[:config_validate] = false
|
96
|
+
destroy_env[:force_confirm_destroy] = true
|
97
|
+
env[:action_runner].run(Action.action_destroy, destroy_env)
|
98
|
+
end
|
91
99
|
end
|
92
100
|
end
|
93
101
|
end
|
@@ -3,7 +3,13 @@ module VagrantPlugins
|
|
3
3
|
module Cap
|
4
4
|
class NicMacAddresses
|
5
5
|
def self.nic_mac_addresses(machine)
|
6
|
-
|
6
|
+
# Vagrant expects a Hash with an index starting at 1 as key
|
7
|
+
# and the mac as uppercase string without colons as value
|
8
|
+
nic_macs = {}
|
9
|
+
machine.provider.mac_addresses.each do |index, mac|
|
10
|
+
nic_macs[index+1] = mac.upcase.gsub(':','')
|
11
|
+
end
|
12
|
+
nic_macs
|
7
13
|
end
|
8
14
|
end
|
9
15
|
end
|
@@ -38,6 +38,7 @@ module VagrantPlugins
|
|
38
38
|
folders.each do |id, folder_opts|
|
39
39
|
folder_opts.merge!({ target: id,
|
40
40
|
accessmode: 'passthrough',
|
41
|
+
mount: true,
|
41
42
|
readonly: nil }) { |_k, ov, _nv| ov }
|
42
43
|
|
43
44
|
mount_tag = Digest::MD5.new.update(folder_opts[:hostpath]).to_s[0,31]
|
@@ -63,9 +64,11 @@ module VagrantPlugins
|
|
63
64
|
# Only mount folders that have a guest path specified.
|
64
65
|
mount_folders = {}
|
65
66
|
folders.each do |id, opts|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
if opts[:mount] && opts[:guestpath] && ! opts[:guestpath].empty?
|
68
|
+
mount_folders[id] = opts.dup
|
69
|
+
# merge common options if not given
|
70
|
+
mount_folders[id].merge!(version: '9p2000.L') { |_k, ov, _nv| ov }
|
71
|
+
end
|
69
72
|
end
|
70
73
|
# Mount the actual folder
|
71
74
|
machine.guest.capability(
|
@@ -48,6 +48,7 @@ module VagrantPlugins
|
|
48
48
|
attr_accessor :management_network_address
|
49
49
|
attr_accessor :management_network_mode
|
50
50
|
attr_accessor :management_network_mac
|
51
|
+
attr_accessor :management_network_guest_ipv6
|
51
52
|
|
52
53
|
# Default host prefix (alternative to use project folder name)
|
53
54
|
attr_accessor :default_prefix
|
@@ -57,6 +58,9 @@ module VagrantPlugins
|
|
57
58
|
attr_accessor :memory
|
58
59
|
attr_accessor :cpus
|
59
60
|
attr_accessor :cpu_mode
|
61
|
+
attr_accessor :cpu_model
|
62
|
+
attr_accessor :cpu_fallback
|
63
|
+
attr_accessor :cpu_features
|
60
64
|
attr_accessor :loader
|
61
65
|
attr_accessor :boot_order
|
62
66
|
attr_accessor :machine_type
|
@@ -69,6 +73,8 @@ module VagrantPlugins
|
|
69
73
|
attr_accessor :kernel
|
70
74
|
attr_accessor :cmd_line
|
71
75
|
attr_accessor :initrd
|
76
|
+
attr_accessor :dtb
|
77
|
+
attr_accessor :emulator_path
|
72
78
|
attr_accessor :graphics_type
|
73
79
|
attr_accessor :graphics_autoport
|
74
80
|
attr_accessor :graphics_port
|
@@ -77,6 +83,13 @@ module VagrantPlugins
|
|
77
83
|
attr_accessor :video_type
|
78
84
|
attr_accessor :video_vram
|
79
85
|
attr_accessor :keymap
|
86
|
+
attr_accessor :kvm_hidden
|
87
|
+
|
88
|
+
# Sets the information for connecting to a host TPM device
|
89
|
+
# Only supports socket-based TPMs
|
90
|
+
attr_accessor :tpm_model
|
91
|
+
attr_accessor :tpm_type
|
92
|
+
attr_accessor :tpm_path
|
80
93
|
|
81
94
|
# Sets the max number of NICs that can be created
|
82
95
|
# Default set to 8. Don't change the default unless you know
|
@@ -90,9 +103,18 @@ module VagrantPlugins
|
|
90
103
|
# Inputs
|
91
104
|
attr_accessor :inputs
|
92
105
|
|
106
|
+
# PCI device passthrough
|
107
|
+
attr_accessor :pcis
|
108
|
+
|
109
|
+
# USB device passthrough
|
110
|
+
attr_accessor :usbs
|
111
|
+
|
93
112
|
# Suspend mode
|
94
113
|
attr_accessor :suspend_mode
|
95
114
|
|
115
|
+
# Autostart
|
116
|
+
attr_accessor :autostart
|
117
|
+
|
96
118
|
def initialize
|
97
119
|
@uri = UNSET_VALUE
|
98
120
|
@driver = UNSET_VALUE
|
@@ -107,12 +129,16 @@ module VagrantPlugins
|
|
107
129
|
@management_network_address = UNSET_VALUE
|
108
130
|
@management_network_mode = UNSET_VALUE
|
109
131
|
@management_network_mac = UNSET_VALUE
|
132
|
+
@management_network_guest_ipv6 = UNSET_VALUE
|
110
133
|
|
111
134
|
# Domain specific settings.
|
112
135
|
@uuid = UNSET_VALUE
|
113
136
|
@memory = UNSET_VALUE
|
114
137
|
@cpus = UNSET_VALUE
|
115
138
|
@cpu_mode = UNSET_VALUE
|
139
|
+
@cpu_model = UNSET_VALUE
|
140
|
+
@cpu_fallback = UNSET_VALUE
|
141
|
+
@cpu_features = UNSET_VALUE
|
116
142
|
@loader = UNSET_VALUE
|
117
143
|
@machine_type = UNSET_VALUE
|
118
144
|
@machine_arch = UNSET_VALUE
|
@@ -123,7 +149,9 @@ module VagrantPlugins
|
|
123
149
|
@volume_cache = UNSET_VALUE
|
124
150
|
@kernel = UNSET_VALUE
|
125
151
|
@initrd = UNSET_VALUE
|
152
|
+
@dtb = UNSET_VALUE
|
126
153
|
@cmd_line = UNSET_VALUE
|
154
|
+
@emulator_path = UNSET_VALUE
|
127
155
|
@graphics_type = UNSET_VALUE
|
128
156
|
@graphics_autoport = UNSET_VALUE
|
129
157
|
@graphics_port = UNSET_VALUE
|
@@ -132,6 +160,11 @@ module VagrantPlugins
|
|
132
160
|
@video_type = UNSET_VALUE
|
133
161
|
@video_vram = UNSET_VALUE
|
134
162
|
@keymap = UNSET_VALUE
|
163
|
+
@kvm_hidden = UNSET_VALUE
|
164
|
+
|
165
|
+
@tpm_model = UNSET_VALUE
|
166
|
+
@tpm_type = UNSET_VALUE
|
167
|
+
@tpm_path = UNSET_VALUE
|
135
168
|
|
136
169
|
@nic_adapter_count = UNSET_VALUE
|
137
170
|
|
@@ -144,8 +177,17 @@ module VagrantPlugins
|
|
144
177
|
# Inputs
|
145
178
|
@inputs = UNSET_VALUE
|
146
179
|
|
180
|
+
# PCI device passthrough
|
181
|
+
@pcis = UNSET_VALUE
|
182
|
+
|
183
|
+
# USB device passthrough
|
184
|
+
@usbs = UNSET_VALUE
|
185
|
+
|
147
186
|
# Suspend mode
|
148
187
|
@suspend_mode = UNSET_VALUE
|
188
|
+
|
189
|
+
# Autostart
|
190
|
+
@autostart = UNSET_VALUE
|
149
191
|
end
|
150
192
|
|
151
193
|
def boot(device)
|
@@ -183,6 +225,21 @@ module VagrantPlugins
|
|
183
225
|
raise 'Only four cdroms may be attached at a time'
|
184
226
|
end
|
185
227
|
|
228
|
+
def cpu_feature(options={})
|
229
|
+
if options[:name].nil? || options[:policy].nil?
|
230
|
+
raise 'CPU Feature name AND policy must be specified'
|
231
|
+
end
|
232
|
+
|
233
|
+
if @cpu_features == UNSET_VALUE
|
234
|
+
@cpu_features = []
|
235
|
+
end
|
236
|
+
|
237
|
+
@cpu_features.push({
|
238
|
+
name: options[:name],
|
239
|
+
policy: options[:policy]
|
240
|
+
})
|
241
|
+
end
|
242
|
+
|
186
243
|
def input(options={})
|
187
244
|
if options[:type].nil? || options[:bus].nil?
|
188
245
|
raise 'Input type AND bus must be specified'
|
@@ -198,6 +255,40 @@ module VagrantPlugins
|
|
198
255
|
})
|
199
256
|
end
|
200
257
|
|
258
|
+
def pci(options={})
|
259
|
+
if options[:bus].nil? || options[:slot].nil? || options[:function].nil?
|
260
|
+
raise 'Bus AND slot AND function must be specified. Check `lspci` for that numbers.'
|
261
|
+
end
|
262
|
+
|
263
|
+
if @pcis == UNSET_VALUE
|
264
|
+
@pcis = []
|
265
|
+
end
|
266
|
+
|
267
|
+
@pcis.push({
|
268
|
+
bus: options[:bus],
|
269
|
+
slot: options[:slot],
|
270
|
+
function: options[:function]
|
271
|
+
})
|
272
|
+
end
|
273
|
+
|
274
|
+
def usb(options={})
|
275
|
+
if (options[:bus].nil? || options[:device].nil?) && options[:vendor].nil? && options[:product].nil?
|
276
|
+
raise 'Bus and device and/or vendor and/or product must be specified. Check `lsusb` for these.'
|
277
|
+
end
|
278
|
+
|
279
|
+
if @usbs == UNSET_VALUE
|
280
|
+
@usbs = []
|
281
|
+
end
|
282
|
+
|
283
|
+
@usbs.push({
|
284
|
+
bus: options[:bus],
|
285
|
+
device: options[:device],
|
286
|
+
vendor: options[:vendor],
|
287
|
+
product: options[:product],
|
288
|
+
startupPolicy: options[:startupPolicy],
|
289
|
+
})
|
290
|
+
end
|
291
|
+
|
201
292
|
# NOTE: this will run twice for each time it's needed- keep it idempotent
|
202
293
|
def storage(storage_type, options={})
|
203
294
|
if storage_type == :file
|
@@ -320,6 +411,7 @@ module VagrantPlugins
|
|
320
411
|
@management_network_address = '192.168.121.0/24' if @management_network_address == UNSET_VALUE
|
321
412
|
@management_network_mode = 'nat' if @management_network_mode == UNSET_VALUE
|
322
413
|
@management_network_mac = nil if @management_network_mac == UNSET_VALUE
|
414
|
+
@management_network_guest_ipv6 = 'yes' if @management_network_guest_ipv6 == UNSET_VALUE
|
323
415
|
|
324
416
|
# generate a URI if none is supplied
|
325
417
|
@uri = _generate_uri() if @uri == UNSET_VALUE
|
@@ -329,6 +421,9 @@ module VagrantPlugins
|
|
329
421
|
@memory = 512 if @memory == UNSET_VALUE
|
330
422
|
@cpus = 1 if @cpus == UNSET_VALUE
|
331
423
|
@cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
|
424
|
+
@cpu_model = 'qemu64' if @cpu_model == UNSET_VALUE
|
425
|
+
@cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
|
426
|
+
@cpu_features = [] if @cpu_features == UNSET_VALUE
|
332
427
|
@loader = nil if @loader == UNSET_VALUE
|
333
428
|
@machine_type = nil if @machine_type == UNSET_VALUE
|
334
429
|
@machine_arch = nil if @machine_arch == UNSET_VALUE
|
@@ -340,6 +435,7 @@ module VagrantPlugins
|
|
340
435
|
@kernel = nil if @kernel == UNSET_VALUE
|
341
436
|
@cmd_line = '' if @cmd_line == UNSET_VALUE
|
342
437
|
@initrd = '' if @initrd == UNSET_VALUE
|
438
|
+
@dtb = nil if @dtb == UNSET_VALUE
|
343
439
|
@graphics_type = 'vnc' if @graphics_type == UNSET_VALUE
|
344
440
|
@graphics_autoport = 'yes' if @graphics_port == UNSET_VALUE
|
345
441
|
@graphics_autoport = 'no' if @graphics_port != UNSET_VALUE
|
@@ -352,7 +448,12 @@ module VagrantPlugins
|
|
352
448
|
@video_type = 'cirrus' if @video_type == UNSET_VALUE
|
353
449
|
@video_vram = 9216 if @video_vram == UNSET_VALUE
|
354
450
|
@keymap = 'en-us' if @keymap == UNSET_VALUE
|
451
|
+
@kvm_hidden = false if @kvm_hidden == UNSET_VALUE
|
452
|
+
@tpm_model = 'tpm-tis' if @tpm_model == UNSET_VALUE
|
453
|
+
@tpm_type = 'passthrough' if @tpm_type == UNSET_VALUE
|
454
|
+
@tpm_path = nil if @tpm_path == UNSET_VALUE
|
355
455
|
@nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE
|
456
|
+
@emulator_path = nil if @emulator_path == UNSET_VALUE
|
356
457
|
|
357
458
|
# Boot order
|
358
459
|
@boot_order = [] if @boot_order == UNSET_VALUE
|
@@ -364,9 +465,17 @@ module VagrantPlugins
|
|
364
465
|
# Inputs
|
365
466
|
@inputs = [{:type => "mouse", :bus => "ps2"}] if @inputs == UNSET_VALUE
|
366
467
|
|
468
|
+
# PCI device passthrough
|
469
|
+
@pcis = [] if @pcis == UNSET_VALUE
|
470
|
+
|
471
|
+
# USB device passthrough
|
472
|
+
@usbs = [] if @usbs == UNSET_VALUE
|
473
|
+
|
367
474
|
# Suspend mode
|
368
475
|
@suspend_mode = "pause" if @suspend_mode == UNSET_VALUE
|
369
476
|
|
477
|
+
# Autostart
|
478
|
+
@autostart = false if @autostart == UNSET_VALUE
|
370
479
|
end
|
371
480
|
|
372
481
|
def validate(machine)
|