vagrant-libvirt 0.3.0 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +421 -50
- data/lib/vagrant-libvirt/action.rb +7 -1
- data/lib/vagrant-libvirt/action/clean_machine_folder.rb +30 -0
- data/lib/vagrant-libvirt/action/create_domain.rb +56 -18
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +57 -55
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +0 -3
- data/lib/vagrant-libvirt/action/create_networks.rb +11 -4
- data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
- data/lib/vagrant-libvirt/action/forward_ports.rb +37 -38
- data/lib/vagrant-libvirt/action/halt_domain.rb +25 -9
- data/lib/vagrant-libvirt/action/handle_box_image.rb +163 -74
- data/lib/vagrant-libvirt/action/is_running.rb +1 -3
- data/lib/vagrant-libvirt/action/is_suspended.rb +4 -4
- data/lib/vagrant-libvirt/action/package_domain.rb +2 -1
- data/lib/vagrant-libvirt/action/set_boot_order.rb +6 -2
- data/lib/vagrant-libvirt/action/start_domain.rb +86 -29
- data/lib/vagrant-libvirt/action/wait_till_up.rb +8 -52
- data/lib/vagrant-libvirt/cap/{mount_p9.rb → mount_9p.rb} +2 -2
- data/lib/vagrant-libvirt/cap/mount_virtiofs.rb +37 -0
- data/lib/vagrant-libvirt/cap/{synced_folder.rb → synced_folder_9p.rb} +4 -5
- data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +109 -0
- data/lib/vagrant-libvirt/config.rb +236 -43
- data/lib/vagrant-libvirt/driver.rb +49 -32
- data/lib/vagrant-libvirt/errors.rb +24 -1
- data/lib/vagrant-libvirt/plugin.rb +14 -5
- data/lib/vagrant-libvirt/provider.rb +2 -9
- data/lib/vagrant-libvirt/templates/domain.xml.erb +35 -10
- data/lib/vagrant-libvirt/templates/private_network.xml.erb +1 -1
- data/lib/vagrant-libvirt/util/network_util.rb +21 -3
- data/lib/vagrant-libvirt/version +1 -1
- data/lib/vagrant-libvirt/version.rb +57 -9
- data/locales/en.yml +12 -0
- data/spec/spec_helper.rb +37 -3
- data/spec/support/binding_proc.rb +24 -0
- data/spec/support/libvirt_context.rb +2 -0
- data/spec/support/matchers/have_file_content.rb +63 -0
- data/spec/support/sharedcontext.rb +4 -0
- data/spec/unit/action/clean_machine_folder_spec.rb +58 -0
- data/spec/unit/action/create_domain_spec.rb +121 -36
- data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +54 -0
- data/spec/unit/action/create_domain_spec/default_domain.xml +49 -0
- data/spec/unit/action/create_domain_spec/{default_storage_pool.xml → default_system_storage_pool.xml} +0 -0
- data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
- data/spec/unit/action/create_domain_volume_spec.rb +102 -0
- data/spec/unit/action/create_domain_volume_spec/one_disk_in_storage.xml +21 -0
- data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_0.xml +21 -0
- data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_1.xml +21 -0
- data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_2.xml +21 -0
- data/spec/unit/action/destroy_domain_spec.rb +1 -1
- data/spec/unit/action/forward_ports_spec.rb +202 -0
- data/spec/unit/action/halt_domain_spec.rb +90 -0
- data/spec/unit/action/handle_box_image_spec.rb +363 -0
- data/spec/unit/action/start_domain_spec.rb +183 -1
- data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
- data/spec/unit/action/start_domain_spec/default.xml +2 -2
- 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 +22 -21
- data/spec/unit/config_spec.rb +395 -127
- data/spec/unit/templates/domain_all_settings.xml +14 -3
- data/spec/unit/templates/domain_custom_cpu_model.xml +2 -1
- data/spec/unit/templates/domain_defaults.xml +2 -1
- data/spec/unit/templates/domain_spec.rb +100 -3
- data/spec/unit/templates/tpm/version_1.2.xml +54 -0
- data/spec/unit/templates/tpm/version_2.0.xml +53 -0
- metadata +105 -19
@@ -49,6 +49,7 @@ module VagrantPlugins
|
|
49
49
|
|
50
50
|
b2.use StartDomain
|
51
51
|
b2.use WaitTillUp
|
52
|
+
b2.use WaitForCommunicator, [:running]
|
52
53
|
|
53
54
|
b2.use ForwardPorts
|
54
55
|
b2.use SetHostname
|
@@ -107,6 +108,7 @@ module VagrantPlugins
|
|
107
108
|
# Machine should gain IP address when comming up,
|
108
109
|
# so wait for dhcp lease and store IP into machines data_dir.
|
109
110
|
b3.use WaitTillUp
|
111
|
+
b3.use WaitForCommunicator, [:running]
|
110
112
|
|
111
113
|
b3.use ForwardPorts
|
112
114
|
b3.use PrepareNFSSettings
|
@@ -179,6 +181,7 @@ module VagrantPlugins
|
|
179
181
|
# Try to remove stale volumes anyway
|
180
182
|
b2.use SetNameOfDomain
|
181
183
|
b2.use RemoveStaleVolume if env[:machine].config.vm.box
|
184
|
+
b2.use CleanMachineFolder, quiet: true
|
182
185
|
b2.use MessageNotCreated unless env[:result]
|
183
186
|
|
184
187
|
next
|
@@ -186,11 +189,12 @@ module VagrantPlugins
|
|
186
189
|
|
187
190
|
b2.use Call, DestroyConfirm do |env2, b3|
|
188
191
|
if env2[:result]
|
192
|
+
b3.use ProvisionerCleanup, :before
|
189
193
|
b3.use ClearForwardedPorts
|
190
194
|
b3.use PruneNFSExports
|
191
195
|
b3.use DestroyDomain
|
192
196
|
b3.use DestroyNetworks
|
193
|
-
b3.use
|
197
|
+
b3.use CleanMachineFolder
|
194
198
|
else
|
195
199
|
b3.use MessageWillNotDestroy
|
196
200
|
end
|
@@ -324,6 +328,7 @@ module VagrantPlugins
|
|
324
328
|
autoload :CreateDomainVolume, action_root.join('create_domain_volume')
|
325
329
|
autoload :CreateNetworkInterfaces, action_root.join('create_network_interfaces')
|
326
330
|
autoload :CreateNetworks, action_root.join('create_networks')
|
331
|
+
autoload :CleanMachineFolder, action_root.join('clean_machine_folder')
|
327
332
|
autoload :DestroyDomain, action_root.join('destroy_domain')
|
328
333
|
autoload :DestroyNetworks, action_root.join('destroy_networks')
|
329
334
|
autoload :ForwardPorts, action_root.join('forward_ports')
|
@@ -366,6 +371,7 @@ module VagrantPlugins
|
|
366
371
|
autoload :SyncedFolders, 'vagrant/action/builtin/synced_folders'
|
367
372
|
autoload :SyncedFolderCleanup, 'vagrant/action/builtin/synced_folder_cleanup'
|
368
373
|
autoload :ProvisionerCleanup, 'vagrant/action/builtin/provisioner_cleanup'
|
374
|
+
autoload :WaitForCommunicator, 'vagrant/action/builtin/wait_for_communicator'
|
369
375
|
end
|
370
376
|
end
|
371
377
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderLibvirt
|
5
|
+
module Action
|
6
|
+
class CleanMachineFolder
|
7
|
+
|
8
|
+
def initialize(app, env, options=nil)
|
9
|
+
@logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain')
|
10
|
+
@app = app
|
11
|
+
@ui = env[:ui]
|
12
|
+
@quiet = (options || {}).fetch(:quiet, false)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
machine_folder = env[:machine].data_dir
|
17
|
+
|
18
|
+
@ui.info("Deleting the machine folder") unless @quiet
|
19
|
+
|
20
|
+
@logger.debug("Recursively removing: #{machine_folder}")
|
21
|
+
FileUtils.rm_rf(machine_folder, :secure => true)
|
22
|
+
# need to recreate to prevent exception during a cancelled up
|
23
|
+
FileUtils.mkdir_p(machine_folder)
|
24
|
+
|
25
|
+
@app.call(env)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -5,6 +5,7 @@ module VagrantPlugins
|
|
5
5
|
module Action
|
6
6
|
class CreateDomain
|
7
7
|
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
8
|
+
include VagrantPlugins::ProviderLibvirt::Util::StorageUtil
|
8
9
|
|
9
10
|
def initialize(app, _env)
|
10
11
|
@logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain')
|
@@ -32,7 +33,8 @@ module VagrantPlugins
|
|
32
33
|
# Gather some info about domain
|
33
34
|
@name = env[:domain_name]
|
34
35
|
@title = config.title
|
35
|
-
|
36
|
+
vagrantfile = File.join(env[:root_path], (env[:vagrantfile_name] || "Vagrantfile"))
|
37
|
+
@description = !config.description.empty? ? config.description : "Source: #{vagrantfile}"
|
36
38
|
@uuid = config.uuid
|
37
39
|
@cpus = config.cpus.to_i
|
38
40
|
@cpuset = config.cpuset
|
@@ -41,6 +43,8 @@ module VagrantPlugins
|
|
41
43
|
@nodeset = config.nodeset
|
42
44
|
@features = config.features
|
43
45
|
@features_hyperv = config.features_hyperv
|
46
|
+
@clock_offset = config.clock_offset
|
47
|
+
@clock_timers = config.clock_timers
|
44
48
|
@shares = config.shares
|
45
49
|
@cpu_mode = config.cpu_mode
|
46
50
|
@cpu_model = config.cpu_model
|
@@ -52,11 +56,12 @@ module VagrantPlugins
|
|
52
56
|
@machine_arch = config.machine_arch
|
53
57
|
@disk_bus = config.disk_bus
|
54
58
|
@disk_device = config.disk_device
|
59
|
+
@disk_driver_opts = config.disk_driver_opts
|
55
60
|
@nested = config.nested
|
56
61
|
@memory_size = config.memory.to_i * 1024
|
57
62
|
@memory_backing = config.memory_backing
|
58
63
|
@management_network_mac = config.management_network_mac
|
59
|
-
@domain_volume_cache = config.volume_cache
|
64
|
+
@domain_volume_cache = config.volume_cache || 'default'
|
60
65
|
@kernel = config.kernel
|
61
66
|
@cmd_line = config.cmd_line
|
62
67
|
@emulator_path = config.emulator_path
|
@@ -80,6 +85,7 @@ module VagrantPlugins
|
|
80
85
|
@tpm_model = config.tpm_model
|
81
86
|
@tpm_type = config.tpm_type
|
82
87
|
@tpm_path = config.tpm_path
|
88
|
+
@tpm_version = config.tpm_version
|
83
89
|
|
84
90
|
# Boot order
|
85
91
|
@boot_order = config.boot_order
|
@@ -87,6 +93,7 @@ module VagrantPlugins
|
|
87
93
|
# Storage
|
88
94
|
@storage_pool_name = config.storage_pool_name
|
89
95
|
@snapshot_pool_name = config.snapshot_pool_name
|
96
|
+
@domain_volumes = []
|
90
97
|
@disks = config.disks
|
91
98
|
@cdroms = config.cdroms
|
92
99
|
|
@@ -136,23 +143,30 @@ module VagrantPlugins
|
|
136
143
|
else
|
137
144
|
pool_name = @storage_pool_name
|
138
145
|
end
|
139
|
-
@logger.debug "Search for
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
146
|
+
@logger.debug "Search for volumes in pool: #{pool_name}"
|
147
|
+
env[:box_volumes].each_index do |index|
|
148
|
+
suffix_index = index > 0 ? "_#{index}" : ''
|
149
|
+
domain_volume = env[:machine].provider.driver.connection.volumes.all(
|
150
|
+
name: "#{@name}#{suffix_index}.img"
|
151
|
+
).find { |x| x.pool_name == pool_name }
|
152
|
+
raise Errors::DomainVolumeExists if domain_volume.nil?
|
153
|
+
@domain_volumes.push({
|
154
|
+
:dev => (index+1).vdev.to_s,
|
155
|
+
:cache => @domain_volume_cache,
|
156
|
+
:bus => @disk_bus,
|
157
|
+
:path => domain_volume.path,
|
158
|
+
:virtual_size => env[:box_volumes][index][:virtual_size]
|
159
|
+
})
|
160
|
+
end
|
145
161
|
end
|
146
162
|
|
147
163
|
# If we have a box, take the path from the domain volume and set our storage_prefix.
|
148
164
|
# If not, we dump the storage pool xml to get its defined path.
|
149
165
|
# the default storage prefix is typically: /var/lib/libvirt/images/
|
150
|
-
if
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
storage_prefix = get_disk_storage_prefix(env, @storage_pool_name)
|
155
|
-
end
|
166
|
+
if env[:machine].config.vm.box
|
167
|
+
storage_prefix = File.dirname(@domain_volumes[0][:path]) + '/' # steal
|
168
|
+
else
|
169
|
+
storage_prefix = get_disk_storage_prefix(env, @storage_pool_name)
|
156
170
|
end
|
157
171
|
|
158
172
|
@disks.each do |disk|
|
@@ -184,6 +198,8 @@ module VagrantPlugins
|
|
184
198
|
format_type: disk[:type],
|
185
199
|
path: disk[:absolute_path],
|
186
200
|
capacity: disk[:size],
|
201
|
+
owner: storage_uid(env),
|
202
|
+
group: storage_gid(env),
|
187
203
|
#:allocation => ?,
|
188
204
|
pool_name: disk_pool_name
|
189
205
|
)
|
@@ -222,7 +238,15 @@ module VagrantPlugins
|
|
222
238
|
env[:ui].info(" -- Feature: #{feature}")
|
223
239
|
end
|
224
240
|
@features_hyperv.each do |feature|
|
225
|
-
|
241
|
+
if feature[:name] == 'spinlocks'
|
242
|
+
env[:ui].info(" -- Feature (HyperV): name=#{feature[:name]}, state=#{feature[:state]}, retries=#{feature[:retries]}")
|
243
|
+
else
|
244
|
+
env[:ui].info(" -- Feature (HyperV): name=#{feature[:name]}, state=#{feature[:state]}")
|
245
|
+
end
|
246
|
+
end
|
247
|
+
env[:ui].info(" -- Clock offset: #{@clock_offset}")
|
248
|
+
@clock_timers.each do |timer|
|
249
|
+
env[:ui].info(" -- Clock timer: #{timer.map { |k,v| "#{k}=#{v}"}.join(', ')}")
|
226
250
|
end
|
227
251
|
env[:ui].info(" -- Memory: #{@memory_size / 1024}M")
|
228
252
|
unless @nodeset.nil?
|
@@ -241,8 +265,16 @@ module VagrantPlugins
|
|
241
265
|
env[:ui].info(" -- Base box: #{env[:machine].box.name}")
|
242
266
|
end
|
243
267
|
env[:ui].info(" -- Storage pool: #{@storage_pool_name}")
|
244
|
-
|
245
|
-
|
268
|
+
@domain_volumes.each do |volume|
|
269
|
+
env[:ui].info(" -- Image(#{volume[:device]}): #{volume[:path]}, #{volume[:virtual_size]}G")
|
270
|
+
end
|
271
|
+
|
272
|
+
if not @disk_driver_opts.empty?
|
273
|
+
env[:ui].info(" -- Disk driver opts: #{@disk_driver_opts.reject { |k,v| v.nil? }.map { |k,v| "#{k}='#{v}'"}.join(' ')}")
|
274
|
+
else
|
275
|
+
env[:ui].info(" -- Disk driver opts: cache='#{@domain_volume_cache}'")
|
276
|
+
end
|
277
|
+
|
246
278
|
env[:ui].info(" -- Kernel: #{@kernel}")
|
247
279
|
env[:ui].info(" -- Initrd: #{@initrd}")
|
248
280
|
env[:ui].info(" -- Graphics Type: #{@graphics_type}")
|
@@ -253,7 +285,13 @@ module VagrantPlugins
|
|
253
285
|
env[:ui].info(" -- Video VRAM: #{@video_vram}")
|
254
286
|
env[:ui].info(" -- Sound Type: #{@sound_type}")
|
255
287
|
env[:ui].info(" -- Keymap: #{@keymap}")
|
256
|
-
env[:ui].info(" -- TPM
|
288
|
+
env[:ui].info(" -- TPM Backend: #{@tpm_type}")
|
289
|
+
if @tpm_type == 'emulator'
|
290
|
+
env[:ui].info(" -- TPM Model: #{@tpm_model}")
|
291
|
+
env[:ui].info(" -- TPM Version: #{@tpm_version}")
|
292
|
+
else
|
293
|
+
env[:ui].info(" -- TPM Path: #{@tpm_path}")
|
294
|
+
end
|
257
295
|
|
258
296
|
@boot_order.each do |device|
|
259
297
|
env[:ui].info(" -- Boot device: #{device}")
|
@@ -18,72 +18,74 @@ module VagrantPlugins
|
|
18
18
|
def call(env)
|
19
19
|
env[:ui].info(I18n.t('vagrant_libvirt.creating_domain_volume'))
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
env[:box_volumes].each_index do |index|
|
22
|
+
suffix_index = index > 0 ? "_#{index}" : ''
|
23
|
+
# Get config options.
|
24
|
+
config = env[:machine].provider_config
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
# This is name of newly created image for vm.
|
27
|
+
@name = "#{env[:domain_name]}#{suffix_index}.img"
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
# Verify the volume doesn't exist already.
|
30
|
+
domain_volume = env[:machine].provider.driver.connection.volumes.all(
|
31
|
+
name: @name
|
32
|
+
).first
|
33
|
+
raise Errors::DomainVolumeExists if domain_volume && domain_volume.id
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
# Get path to backing image - box volume.
|
36
|
+
box_volume = env[:machine].provider.driver.connection.volumes.all(
|
37
|
+
name: env[:box_volumes][index][:name]
|
38
|
+
).first
|
39
|
+
@backing_file = box_volume.path
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
+
# Virtual size of image. Take value worked out by HandleBoxImage
|
42
|
+
@capacity = env[:box_volumes][index][:virtual_size] # G
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
# Create new volume from xml template. Fog currently doesn't support
|
45
|
+
# volume snapshots directly.
|
46
|
+
begin
|
47
|
+
xml = Nokogiri::XML::Builder.new do |xml|
|
48
|
+
xml.volume do
|
49
|
+
xml.name(@name)
|
50
|
+
xml.capacity(@capacity, unit: 'G')
|
51
|
+
xml.target do
|
52
|
+
xml.format(type: 'qcow2')
|
53
|
+
xml.permissions do
|
54
|
+
xml.owner storage_uid(env)
|
55
|
+
xml.group storage_gid(env)
|
56
|
+
xml.label 'virt_image_t'
|
57
|
+
end
|
55
58
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
xml.backingStore do
|
60
|
+
xml.path(@backing_file)
|
61
|
+
xml.format(type: 'qcow2')
|
62
|
+
xml.permissions do
|
63
|
+
xml.owner storage_uid(env)
|
64
|
+
xml.group storage_gid(env)
|
65
|
+
xml.label 'virt_image_t'
|
66
|
+
end
|
64
67
|
end
|
65
68
|
end
|
69
|
+
end.to_xml(
|
70
|
+
save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION |
|
71
|
+
Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
|
72
|
+
Nokogiri::XML::Node::SaveOptions::FORMAT
|
73
|
+
)
|
74
|
+
if config.snapshot_pool_name != config.storage_pool_name
|
75
|
+
pool_name = config.snapshot_pool_name
|
76
|
+
else
|
77
|
+
pool_name = config.storage_pool_name
|
66
78
|
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
pool_name = config.storage_pool_name
|
79
|
+
@logger.debug "Using pool #{pool_name} for base box snapshot"
|
80
|
+
domain_volume = env[:machine].provider.driver.connection.volumes.create(
|
81
|
+
xml: xml,
|
82
|
+
pool_name: pool_name
|
83
|
+
)
|
84
|
+
rescue Fog::Errors::Error => e
|
85
|
+
raise Errors::FogDomainVolumeCreateError,
|
86
|
+
error_message: e.message
|
76
87
|
end
|
77
|
-
@logger.debug "Using pool #{pool_name} for base box snapshot"
|
78
|
-
domain_volume = env[:machine].provider.driver.connection.volumes.create(
|
79
|
-
xml: xml,
|
80
|
-
pool_name: pool_name
|
81
|
-
)
|
82
|
-
rescue Fog::Errors::Error => e
|
83
|
-
raise Errors::FogDomainVolumeCreateError,
|
84
|
-
error_message: e.message
|
85
88
|
end
|
86
|
-
|
87
89
|
@app.call(env)
|
88
90
|
end
|
89
91
|
end
|
@@ -54,6 +54,8 @@ module VagrantPlugins
|
|
54
54
|
env[:machine].provider.driver.connection.client
|
55
55
|
)
|
56
56
|
|
57
|
+
current_network = @available_networks.detect { |network| network[:name] == @options[:network_name] }
|
58
|
+
|
57
59
|
# Prepare a hash describing network for this specific interface.
|
58
60
|
@interface_network = {
|
59
61
|
name: nil,
|
@@ -64,11 +66,11 @@ module VagrantPlugins
|
|
64
66
|
domain_name: nil,
|
65
67
|
ipv6_address: options[:ipv6_address] || nil,
|
66
68
|
ipv6_prefix: options[:ipv6_prefix] || nil,
|
67
|
-
created: false,
|
68
|
-
active: false,
|
69
|
+
created: current_network.nil? ? false : true,
|
70
|
+
active: current_network.nil? ? false : current_network[:active],
|
69
71
|
autostart: options[:autostart] || false,
|
70
72
|
guest_ipv6: @options[:guest_ipv6] || 'yes',
|
71
|
-
libvirt_network: nil
|
73
|
+
libvirt_network: current_network.nil? ? nil : current_network[:libvirt_network]
|
72
74
|
}
|
73
75
|
|
74
76
|
if @options[:ip]
|
@@ -255,7 +257,9 @@ module VagrantPlugins
|
|
255
257
|
|
256
258
|
# Do we need to create new network?
|
257
259
|
unless @interface_network[:created]
|
258
|
-
@interface_network[:name] =
|
260
|
+
@interface_network[:name] = @options[:network_name] ?
|
261
|
+
@options[:network_name] :
|
262
|
+
'vagrant-private-dhcp'
|
259
263
|
@interface_network[:network_address] = net_address
|
260
264
|
|
261
265
|
# Set IP address of network (actually bridge). It will be used as
|
@@ -297,6 +301,9 @@ module VagrantPlugins
|
|
297
301
|
|
298
302
|
@network_ipv6_address = @interface_network[:ipv6_address]
|
299
303
|
@network_ipv6_prefix = @interface_network[:ipv6_prefix]
|
304
|
+
|
305
|
+
@network_bridge_stp = @options[:bridge_stp].nil? || @options[:bridge_stp] ? 'on' : 'off'
|
306
|
+
@network_bridge_delay = @options[:bridge_delay] ? @options[:bridge_delay] : 0
|
300
307
|
|
301
308
|
@network_forward_mode = @options[:forward_mode]
|
302
309
|
if @options[:forward_device]
|
@@ -11,10 +11,8 @@ module VagrantPlugins
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
-
@env = env
|
15
|
-
|
16
14
|
# Get the ports we're forwarding
|
17
|
-
env[:forwarded_ports] = compile_forwarded_ports(env[:machine].config)
|
15
|
+
env[:forwarded_ports] = compile_forwarded_ports(env, env[:machine].config)
|
18
16
|
|
19
17
|
# Warn if we're port forwarding to any privileged ports
|
20
18
|
env[:forwarded_ports].each do |fp|
|
@@ -28,51 +26,52 @@ module VagrantPlugins
|
|
28
26
|
# Continue, we need the VM to be booted in order to grab its IP
|
29
27
|
@app.call env
|
30
28
|
|
31
|
-
if
|
29
|
+
if env[:forwarded_ports].any?
|
32
30
|
env[:ui].info I18n.t('vagrant.actions.vm.forward_ports.forwarding')
|
33
|
-
forward_ports
|
31
|
+
forward_ports(env)
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
|
-
def forward_ports
|
38
|
-
|
35
|
+
def forward_ports(env)
|
36
|
+
env[:forwarded_ports].each do |fp|
|
39
37
|
message_attributes = {
|
40
38
|
adapter: fp[:adapter] || 'eth0',
|
41
39
|
guest_port: fp[:guest],
|
42
40
|
host_port: fp[:host]
|
43
41
|
}
|
44
42
|
|
45
|
-
|
43
|
+
env[:ui].info(I18n.t(
|
46
44
|
'vagrant.actions.vm.forward_ports.forwarding_entry',
|
47
|
-
message_attributes
|
45
|
+
**message_attributes
|
48
46
|
))
|
49
47
|
|
50
|
-
if fp[:protocol] == 'udp'
|
51
|
-
@env[:ui].warn I18n.t('vagrant_libvirt.warnings.forwarding_udp')
|
52
|
-
next
|
53
|
-
end
|
54
|
-
|
55
48
|
ssh_pid = redirect_port(
|
56
|
-
|
49
|
+
env,
|
50
|
+
env[:machine],
|
57
51
|
fp[:host_ip] || '*',
|
58
52
|
fp[:host],
|
59
|
-
fp[:guest_ip] ||
|
53
|
+
fp[:guest_ip] || env[:machine].provider.ssh_info[:host],
|
60
54
|
fp[:guest],
|
61
55
|
fp[:gateway_ports] || false
|
62
56
|
)
|
63
|
-
store_ssh_pid(fp[:host], ssh_pid)
|
57
|
+
store_ssh_pid(env[:machine], fp[:host], ssh_pid)
|
64
58
|
end
|
65
59
|
end
|
66
60
|
|
67
61
|
private
|
68
62
|
|
69
|
-
def compile_forwarded_ports(config)
|
63
|
+
def compile_forwarded_ports(env, config)
|
70
64
|
mappings = {}
|
71
65
|
|
72
66
|
config.vm.networks.each do |type, options|
|
73
67
|
next if options[:disabled]
|
74
68
|
|
75
|
-
|
69
|
+
if options[:protocol] == 'udp'
|
70
|
+
env[:ui].warn I18n.t('vagrant_libvirt.warnings.forwarding_udp')
|
71
|
+
next
|
72
|
+
end
|
73
|
+
|
74
|
+
next if type != :forwarded_port || ( options[:id] == 'ssh' && !env[:machine].provider_config.forward_ssh_port )
|
76
75
|
if options.fetch(:host_ip, '').to_s.strip.empty?
|
77
76
|
options.delete(:host_ip)
|
78
77
|
end
|
@@ -82,7 +81,7 @@ module VagrantPlugins
|
|
82
81
|
mappings.values
|
83
82
|
end
|
84
83
|
|
85
|
-
def redirect_port(machine, host_ip, host_port, guest_ip, guest_port,
|
84
|
+
def redirect_port(env, machine, host_ip, host_port, guest_ip, guest_port,
|
86
85
|
gateway_ports)
|
87
86
|
ssh_info = machine.ssh_info
|
88
87
|
params = %W(
|
@@ -107,14 +106,14 @@ module VagrantPlugins
|
|
107
106
|
"IdentityFile='\"#{pk}\"'"
|
108
107
|
end).map { |s| s.prepend('-o ') }.join(' ')
|
109
108
|
|
110
|
-
options += " -o ProxyCommand=\"#{ssh_info[:proxy_command]}\"" if machine.provider_config.
|
109
|
+
options += " -o ProxyCommand=\"#{ssh_info[:proxy_command]}\"" if machine.provider_config.proxy_command
|
111
110
|
|
112
111
|
# TODO: instead of this, try and lock and get the stdin from spawn...
|
113
112
|
ssh_cmd = ''
|
114
113
|
if host_port <= 1024
|
115
114
|
@@lock.synchronize do
|
116
115
|
# TODO: add i18n
|
117
|
-
|
116
|
+
env[:ui].info 'Requesting sudo for host port(s) <= 1024'
|
118
117
|
r = system('sudo -v')
|
119
118
|
if r
|
120
119
|
ssh_cmd << 'sudo ' # add sudo prefix
|
@@ -125,14 +124,15 @@ module VagrantPlugins
|
|
125
124
|
ssh_cmd << "ssh -n #{options} #{params}"
|
126
125
|
|
127
126
|
@logger.debug "Forwarding port with `#{ssh_cmd}`"
|
128
|
-
log_file = ssh_forward_log_file(
|
129
|
-
|
127
|
+
log_file = ssh_forward_log_file(
|
128
|
+
env[:machine], host_ip, host_port, guest_ip, guest_port,
|
129
|
+
)
|
130
130
|
@logger.info "Logging to #{log_file}"
|
131
131
|
spawn(ssh_cmd, [:out, :err] => [log_file, 'w'], :pgroup => true)
|
132
132
|
end
|
133
133
|
|
134
|
-
def ssh_forward_log_file(host_ip, host_port, guest_ip, guest_port)
|
135
|
-
log_dir =
|
134
|
+
def ssh_forward_log_file(machine, host_ip, host_port, guest_ip, guest_port)
|
135
|
+
log_dir = machine.data_dir.join('logs')
|
136
136
|
log_dir.mkdir unless log_dir.directory?
|
137
137
|
File.join(
|
138
138
|
log_dir,
|
@@ -141,8 +141,8 @@ module VagrantPlugins
|
|
141
141
|
)
|
142
142
|
end
|
143
143
|
|
144
|
-
def store_ssh_pid(host_port, ssh_pid)
|
145
|
-
data_dir =
|
144
|
+
def store_ssh_pid(machine, host_port, ssh_pid)
|
145
|
+
data_dir = machine.data_dir.join('pids')
|
146
146
|
data_dir.mkdir unless data_dir.directory?
|
147
147
|
|
148
148
|
data_dir.join("ssh_#{host_port}.pid").open('w') do |pid_file|
|
@@ -169,13 +169,12 @@ module VagrantPlugins
|
|
169
169
|
end
|
170
170
|
|
171
171
|
def call(env)
|
172
|
-
|
173
|
-
|
174
|
-
if ssh_pids.any?
|
172
|
+
pids = ssh_pids(env[:machine])
|
173
|
+
if pids.any?
|
175
174
|
env[:ui].info I18n.t(
|
176
175
|
'vagrant.actions.vm.clear_forward_ports.deleting'
|
177
176
|
)
|
178
|
-
|
177
|
+
pids.each do |tag|
|
179
178
|
next unless ssh_pid?(tag[:pid])
|
180
179
|
@logger.debug "Killing pid #{tag[:pid]}"
|
181
180
|
kill_cmd = ''
|
@@ -191,7 +190,7 @@ module VagrantPlugins
|
|
191
190
|
end
|
192
191
|
|
193
192
|
@logger.info 'Removing ssh pid files'
|
194
|
-
remove_ssh_pids
|
193
|
+
remove_ssh_pids(env[:machine])
|
195
194
|
else
|
196
195
|
@logger.info 'No ssh pids found'
|
197
196
|
end
|
@@ -201,9 +200,9 @@ module VagrantPlugins
|
|
201
200
|
|
202
201
|
protected
|
203
202
|
|
204
|
-
def ssh_pids
|
205
|
-
glob =
|
206
|
-
|
203
|
+
def ssh_pids(machine)
|
204
|
+
glob = machine.data_dir.join('pids').to_s + '/ssh_*.pid'
|
205
|
+
ssh_pids = Dir[glob].map do |file|
|
207
206
|
{
|
208
207
|
pid: File.read(file).strip.chomp,
|
209
208
|
port: File.basename(file)['ssh_'.length..-1 * ('.pid'.length + 1)].to_i
|
@@ -217,8 +216,8 @@ module VagrantPlugins
|
|
217
216
|
`ps -o command= #{pid}`.strip.chomp =~ /ssh/
|
218
217
|
end
|
219
218
|
|
220
|
-
def remove_ssh_pids
|
221
|
-
glob =
|
219
|
+
def remove_ssh_pids(machine)
|
220
|
+
glob = machine.data_dir.join('pids').to_s + '/ssh_*.pid'
|
222
221
|
Dir[glob].each do |file|
|
223
222
|
File.delete file
|
224
223
|
end
|