vagrant-libvirt 0.0.32 → 0.0.33
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|