vagrant-libvirt 0.0.40 → 0.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. metadata +13 -103
  3. data/.coveralls.yml +0 -1
  4. data/.github/issue_template.md +0 -37
  5. data/.gitignore +0 -21
  6. data/.travis.yml +0 -28
  7. data/CHANGELOG.md +0 -99
  8. data/Gemfile +0 -27
  9. data/LICENSE +0 -22
  10. data/README.md +0 -1311
  11. data/Rakefile +0 -8
  12. data/example_box/README.md +0 -29
  13. data/example_box/Vagrantfile +0 -60
  14. data/example_box/metadata.json +0 -5
  15. data/lib/vagrant-libvirt.rb +0 -29
  16. data/lib/vagrant-libvirt/action.rb +0 -362
  17. data/lib/vagrant-libvirt/action/create_domain.rb +0 -313
  18. data/lib/vagrant-libvirt/action/create_domain_volume.rb +0 -87
  19. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +0 -294
  20. data/lib/vagrant-libvirt/action/create_networks.rb +0 -353
  21. data/lib/vagrant-libvirt/action/destroy_domain.rb +0 -83
  22. data/lib/vagrant-libvirt/action/destroy_networks.rb +0 -95
  23. data/lib/vagrant-libvirt/action/forward_ports.rb +0 -221
  24. data/lib/vagrant-libvirt/action/halt_domain.rb +0 -35
  25. data/lib/vagrant-libvirt/action/handle_box_image.rb +0 -156
  26. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +0 -57
  27. data/lib/vagrant-libvirt/action/is_created.rb +0 -18
  28. data/lib/vagrant-libvirt/action/is_running.rb +0 -21
  29. data/lib/vagrant-libvirt/action/is_suspended.rb +0 -42
  30. data/lib/vagrant-libvirt/action/message_already_created.rb +0 -16
  31. data/lib/vagrant-libvirt/action/message_not_created.rb +0 -16
  32. data/lib/vagrant-libvirt/action/message_not_running.rb +0 -16
  33. data/lib/vagrant-libvirt/action/message_not_suspended.rb +0 -16
  34. data/lib/vagrant-libvirt/action/package_domain.rb +0 -105
  35. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +0 -94
  36. data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +0 -17
  37. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +0 -27
  38. data/lib/vagrant-libvirt/action/read_mac_addresses.rb +0 -40
  39. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +0 -20
  40. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +0 -50
  41. data/lib/vagrant-libvirt/action/resume_domain.rb +0 -34
  42. data/lib/vagrant-libvirt/action/set_boot_order.rb +0 -109
  43. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +0 -64
  44. data/lib/vagrant-libvirt/action/share_folders.rb +0 -71
  45. data/lib/vagrant-libvirt/action/start_domain.rb +0 -303
  46. data/lib/vagrant-libvirt/action/suspend_domain.rb +0 -40
  47. data/lib/vagrant-libvirt/action/wait_till_up.rb +0 -102
  48. data/lib/vagrant-libvirt/cap/mount_p9.rb +0 -42
  49. data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +0 -17
  50. data/lib/vagrant-libvirt/cap/synced_folder.rb +0 -113
  51. data/lib/vagrant-libvirt/config.rb +0 -698
  52. data/lib/vagrant-libvirt/driver.rb +0 -118
  53. data/lib/vagrant-libvirt/errors.rb +0 -149
  54. data/lib/vagrant-libvirt/plugin.rb +0 -92
  55. data/lib/vagrant-libvirt/provider.rb +0 -130
  56. data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +0 -13
  57. data/lib/vagrant-libvirt/templates/domain.xml.erb +0 -229
  58. data/lib/vagrant-libvirt/templates/private_network.xml.erb +0 -34
  59. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +0 -23
  60. data/lib/vagrant-libvirt/util.rb +0 -11
  61. data/lib/vagrant-libvirt/util/collection.rb +0 -19
  62. data/lib/vagrant-libvirt/util/erb_template.rb +0 -22
  63. data/lib/vagrant-libvirt/util/error_codes.rb +0 -100
  64. data/lib/vagrant-libvirt/util/network_util.rb +0 -138
  65. data/lib/vagrant-libvirt/util/timer.rb +0 -17
  66. data/lib/vagrant-libvirt/version.rb +0 -5
  67. data/locales/en.yml +0 -159
  68. data/spec/spec_helper.rb +0 -9
  69. data/spec/support/environment_helper.rb +0 -46
  70. data/spec/support/libvirt_context.rb +0 -30
  71. data/spec/support/sharedcontext.rb +0 -34
  72. data/spec/unit/action/destroy_domain_spec.rb +0 -97
  73. data/spec/unit/action/set_name_of_domain_spec.rb +0 -21
  74. data/spec/unit/action/wait_till_up_spec.rb +0 -127
  75. data/spec/unit/config_spec.rb +0 -106
  76. data/spec/unit/templates/domain_all_settings.xml +0 -133
  77. data/spec/unit/templates/domain_defaults.xml +0 -46
  78. data/spec/unit/templates/domain_spec.rb +0 -75
  79. data/tools/create_box.sh +0 -130
  80. data/tools/prepare_redhat_for_box.sh +0 -119
  81. data/vagrant-libvirt.gemspec +0 -28
@@ -1,313 +0,0 @@
1
- require 'log4r'
2
-
3
- module VagrantPlugins
4
- module ProviderLibvirt
5
- module Action
6
- class CreateDomain
7
- include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
8
-
9
- def initialize(app, _env)
10
- @logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain')
11
- @app = app
12
- end
13
-
14
- def _disk_name(name, disk)
15
- "#{name}-#{disk[:device]}.#{disk[:type]}" # disk name
16
- end
17
-
18
- def _disks_print(disks)
19
- disks.collect do |x|
20
- "#{x[:device]}(#{x[:type]},#{x[:size]})"
21
- end.join(', ')
22
- end
23
-
24
- def _cdroms_print(cdroms)
25
- cdroms.collect { |x| x[:dev] }.join(', ')
26
- end
27
-
28
- def call(env)
29
- # Get config.
30
- config = env[:machine].provider_config
31
-
32
- # Gather some info about domain
33
- @name = env[:domain_name]
34
- @uuid = config.uuid
35
- @cpus = config.cpus.to_i
36
- @cpu_features = config.cpu_features
37
- @features = config.features
38
- @cpu_mode = config.cpu_mode
39
- @cpu_model = config.cpu_model
40
- @cpu_fallback = config.cpu_fallback
41
- @numa_nodes = config.numa_nodes
42
- @loader = config.loader
43
- @machine_type = config.machine_type
44
- @machine_arch = config.machine_arch
45
- @disk_bus = config.disk_bus
46
- @disk_device = config.disk_device
47
- @nested = config.nested
48
- @memory_size = config.memory.to_i * 1024
49
- @management_network_mac = config.management_network_mac
50
- @domain_volume_cache = config.volume_cache
51
- @kernel = config.kernel
52
- @cmd_line = config.cmd_line
53
- @emulator_path = config.emulator_path
54
- @initrd = config.initrd
55
- @dtb = config.dtb
56
- @graphics_type = config.graphics_type
57
- @graphics_autoport = config.graphics_autoport
58
- @graphics_port = config.graphics_port
59
- @graphics_ip = config.graphics_ip
60
- @graphics_passwd = if config.graphics_passwd.to_s.empty?
61
- ''
62
- else
63
- "passwd='#{config.graphics_passwd}'"
64
- end
65
- @video_type = config.video_type
66
- @sound_type = config.sound_type
67
- @video_vram = config.video_vram
68
- @keymap = config.keymap
69
- @kvm_hidden = config.kvm_hidden
70
-
71
- @tpm_model = config.tpm_model
72
- @tpm_type = config.tpm_type
73
- @tpm_path = config.tpm_path
74
-
75
- # Boot order
76
- @boot_order = config.boot_order
77
-
78
- # Storage
79
- @storage_pool_name = config.storage_pool_name
80
- @disks = config.disks
81
- @cdroms = config.cdroms
82
-
83
- # Input
84
- @inputs = config.inputs
85
-
86
- # Channels
87
- @channels = config.channels
88
-
89
- # PCI device passthrough
90
- @pcis = config.pcis
91
-
92
- # Watchdog device
93
- @watchdog_dev = config.watchdog_dev
94
-
95
- # USB device passthrough
96
- @usbs = config.usbs
97
-
98
- # Redirected devices
99
- @redirdevs = config.redirdevs
100
- @redirfilters = config.redirfilters
101
-
102
- # smartcard device
103
- @smartcard_dev = config.smartcard_dev
104
-
105
- # RNG device passthrough
106
- @rng = config.rng
107
-
108
- config = env[:machine].provider_config
109
- @domain_type = config.driver
110
-
111
- @os_type = 'hvm'
112
-
113
- # Get path to domain image from the storage pool selected if we have a box.
114
- if env[:machine].config.vm.box
115
- actual_volumes =
116
- env[:machine].provider.driver.connection.volumes.all.select do |x|
117
- x.pool_name == @storage_pool_name
118
- end
119
- domain_volume = ProviderLibvirt::Util::Collection.find_matching(
120
- actual_volumes, "#{@name}.img"
121
- )
122
- raise Errors::DomainVolumeExists if domain_volume.nil?
123
- @domain_volume_path = domain_volume.path
124
- end
125
-
126
- # If we have a box, take the path from the domain volume and set our storage_prefix.
127
- # If not, we dump the storage pool xml to get its defined path.
128
- # the default storage prefix is typically: /var/lib/libvirt/images/
129
- if env[:machine].config.vm.box
130
- storage_prefix = File.dirname(@domain_volume_path) + '/' # steal
131
- else
132
- storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name)
133
- raise Errors::NoStoragePool if storage_pool.nil?
134
- xml = Nokogiri::XML(storage_pool.xml_desc)
135
- storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/'
136
- end
137
-
138
- @disks.each do |disk|
139
- disk[:path] ||= _disk_name(@name, disk)
140
-
141
- # On volume creation, the <path> element inside <target>
142
- # is oddly ignored; instead the path is taken from the
143
- # <name> element:
144
- # http://www.redhat.com/archives/libvir-list/2008-August/msg00329.html
145
- disk[:name] = disk[:path]
146
-
147
- disk[:absolute_path] = storage_prefix + disk[:path]
148
-
149
- if env[:machine].provider.driver.connection.volumes.select do |x|
150
- x.name == disk[:name] && x.pool_name == @storage_pool_name
151
- end.empty?
152
- # make the disk. equivalent to:
153
- # qemu-img create -f qcow2 <path> 5g
154
- begin
155
- env[:machine].provider.driver.connection.volumes.create(
156
- name: disk[:name],
157
- format_type: disk[:type],
158
- path: disk[:absolute_path],
159
- capacity: disk[:size],
160
- #:allocation => ?,
161
- pool_name: @storage_pool_name
162
- )
163
- rescue Fog::Errors::Error => e
164
- raise Errors::FogDomainVolumeCreateError,
165
- error_message: e.message
166
- end
167
- else
168
- disk[:preexisting] = true
169
- end
170
- end
171
-
172
- # Output the settings we're going to use to the user
173
- env[:ui].info(I18n.t('vagrant_libvirt.creating_domain'))
174
- env[:ui].info(" -- Name: #{@name}")
175
- env[:ui].info(" -- Forced UUID: #{@uuid}") if @uuid != ''
176
- env[:ui].info(" -- Domain type: #{@domain_type}")
177
- env[:ui].info(" -- Cpus: #{@cpus}")
178
- @cpu_features.each do |cpu_feature|
179
- env[:ui].info(" -- CPU Feature: name=#{cpu_feature[:name]}, policy=#{cpu_feature[:policy]}")
180
- end
181
- @features.each do |feature|
182
- env[:ui].info(" -- Feature: #{feature}")
183
- end
184
- env[:ui].info(" -- Memory: #{@memory_size / 1024}M")
185
- env[:ui].info(" -- Management MAC: #{@management_network_mac}")
186
- env[:ui].info(" -- Loader: #{@loader}")
187
- if env[:machine].config.vm.box
188
- env[:ui].info(" -- Base box: #{env[:machine].box.name}")
189
- end
190
- env[:ui].info(" -- Storage pool: #{@storage_pool_name}")
191
- env[:ui].info(" -- Image: #{@domain_volume_path} (#{env[:box_virtual_size]}G)")
192
- env[:ui].info(" -- Volume Cache: #{@domain_volume_cache}")
193
- env[:ui].info(" -- Kernel: #{@kernel}")
194
- env[:ui].info(" -- Initrd: #{@initrd}")
195
- env[:ui].info(" -- Graphics Type: #{@graphics_type}")
196
- env[:ui].info(" -- Graphics Port: #{@graphics_port}")
197
- env[:ui].info(" -- Graphics IP: #{@graphics_ip}")
198
- env[:ui].info(" -- Graphics Password: #{@graphics_passwd.empty? ? 'Not defined' : 'Defined'}")
199
- env[:ui].info(" -- Video Type: #{@video_type}")
200
- env[:ui].info(" -- Video VRAM: #{@video_vram}")
201
- env[:ui].info(" -- Sound Type: #{@sound_type}")
202
- env[:ui].info(" -- Keymap: #{@keymap}")
203
- env[:ui].info(" -- TPM Path: #{@tpm_path}")
204
-
205
- @boot_order.each do |device|
206
- env[:ui].info(" -- Boot device: #{device}")
207
- end
208
-
209
- unless @disks.empty?
210
- env[:ui].info(" -- Disks: #{_disks_print(@disks)}")
211
- end
212
-
213
- @disks.each do |disk|
214
- msg = " -- Disk(#{disk[:device]}): #{disk[:absolute_path]}"
215
- msg += ' Shared' if disk[:shareable]
216
- msg += ' (Remove only manually)' if disk[:allow_existing]
217
- msg += ' Not created - using existed.' if disk[:preexisting]
218
- env[:ui].info(msg)
219
- end
220
-
221
- unless @cdroms.empty?
222
- env[:ui].info(" -- CDROMS: #{_cdroms_print(@cdroms)}")
223
- end
224
-
225
- @cdroms.each do |cdrom|
226
- env[:ui].info(" -- CDROM(#{cdrom[:dev]}): #{cdrom[:path]}")
227
- end
228
-
229
- @inputs.each do |input|
230
- env[:ui].info(" -- INPUT: type=#{input[:type]}, bus=#{input[:bus]}")
231
- end
232
-
233
- @channels.each do |channel|
234
- env[:ui].info(" -- CHANNEL: type=#{channel[:type]}, mode=#{channel[:source_mode]}")
235
- env[:ui].info(" -- CHANNEL: target_type=#{channel[:target_type]}, target_name=#{channel[:target_name]}")
236
- end
237
-
238
- @pcis.each do |pci|
239
- env[:ui].info(" -- PCI passthrough: #{pci[:bus]}:#{pci[:slot]}.#{pci[:function]}")
240
- end
241
-
242
- unless @rng[:model].nil?
243
- env[:ui].info(" -- RNG device model: #{@rng[:model]}")
244
- end
245
-
246
- if not @watchdog_dev.empty?
247
- env[:ui].info(" -- Watchdog device: model=#{@watchdog_dev[:model]}, action=#{@watchdog_dev[:action]}")
248
- end
249
-
250
- @usbs.each do |usb|
251
- usb_dev = []
252
- usb_dev.push("bus=#{usb[:bus]}") if usb[:bus]
253
- usb_dev.push("device=#{usb[:device]}") if usb[:device]
254
- usb_dev.push("vendor=#{usb[:vendor]}") if usb[:vendor]
255
- usb_dev.push("product=#{usb[:product]}") if usb[:product]
256
- env[:ui].info(" -- USB passthrough: #{usb_dev.join(', ')}")
257
- end
258
-
259
- unless @redirdevs.empty?
260
- env[:ui].info(' -- Redirected Devices: ')
261
- @redirdevs.each do |redirdev|
262
- msg = " -> bus=usb, type=#{redirdev[:type]}"
263
- env[:ui].info(msg)
264
- end
265
- end
266
-
267
- unless @redirfilters.empty?
268
- env[:ui].info(' -- USB Device filter for Redirected Devices: ')
269
- @redirfilters.each do |redirfilter|
270
- msg = " -> class=#{redirfilter[:class]}, "
271
- msg += "vendor=#{redirfilter[:vendor]}, "
272
- msg += "product=#{redirfilter[:product]}, "
273
- msg += "version=#{redirfilter[:version]}, "
274
- msg += "allow=#{redirfilter[:allow]}"
275
- env[:ui].info(msg)
276
- end
277
- end
278
-
279
- if not @smartcard_dev.empty?
280
- env[:ui].info(" -- smartcard device: mode=#{@smartcard_dev[:mode]}, type=#{@smartcard_dev[:type]}")
281
- end
282
-
283
- @qargs = config.qemu_args
284
- if not @qargs.empty?
285
- env[:ui].info(' -- Command line args: ')
286
- @qargs.each do |arg|
287
- msg = " -> value=#{arg[:value]}, "
288
- env[:ui].info(msg)
289
- end
290
- end
291
-
292
- env[:ui].info(" -- Command line : #{@cmd_line}") unless @cmd_line.empty?
293
-
294
- # Create libvirt domain.
295
- # Is there a way to tell fog to create new domain with already
296
- # existing volume? Use domain creation from template..
297
- begin
298
- server = env[:machine].provider.driver.connection.servers.create(
299
- xml: to_xml('domain')
300
- )
301
- rescue Fog::Errors::Error => e
302
- raise Errors::FogCreateServerError, error_message: e.message
303
- end
304
-
305
- # Immediately save the ID since it is created at this point.
306
- env[:machine].id = server.id
307
-
308
- @app.call(env)
309
- end
310
- end
311
- end
312
- end
313
- end
@@ -1,87 +0,0 @@
1
- require 'log4r'
2
-
3
- module VagrantPlugins
4
- module ProviderLibvirt
5
- module Action
6
- # Create a snapshot of base box image. This new snapshot is just new
7
- # cow image with backing storage pointing to base box image. Use this
8
- # image as new domain volume.
9
- class CreateDomainVolume
10
- include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
11
-
12
- def initialize(app, _env)
13
- @logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain_volume')
14
- @app = app
15
- end
16
-
17
- def call(env)
18
- env[:ui].info(I18n.t('vagrant_libvirt.creating_domain_volume'))
19
-
20
- # Get config options.
21
- config = env[:machine].provider_config
22
-
23
- # This is name of newly created image for vm.
24
- @name = "#{env[:domain_name]}.img"
25
-
26
- # Verify the volume doesn't exist already.
27
- domain_volume = ProviderLibvirt::Util::Collection.find_matching(
28
- env[:machine].provider.driver.connection.volumes.all, @name
29
- )
30
- raise Errors::DomainVolumeExists if domain_volume
31
-
32
- # Get path to backing image - box volume.
33
- box_volume = ProviderLibvirt::Util::Collection.find_matching(
34
- env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name]
35
- )
36
- @backing_file = box_volume.path
37
-
38
- # Virtual size of image. Take value worked out by HandleBoxImage
39
- @capacity = env[:box_virtual_size] # G
40
-
41
- # Create new volume from xml template. Fog currently doesn't support
42
- # volume snapshots directly.
43
- begin
44
- xml = Nokogiri::XML::Builder.new do |xml|
45
- xml.volume do
46
- xml.name(@name)
47
- xml.capacity(@capacity, unit: 'G')
48
- xml.target do
49
- xml.format(type: 'qcow2')
50
- xml.permissions do
51
- xml.owner 0
52
- xml.group 0
53
- xml.mode '0600'
54
- xml.label 'virt_image_t'
55
- end
56
- end
57
- xml.backingStore do
58
- xml.path(@backing_file)
59
- xml.format(type: 'qcow2')
60
- xml.permissions do
61
- xml.owner 0
62
- xml.group 0
63
- xml.mode '0600'
64
- xml.label 'virt_image_t'
65
- end
66
- end
67
- end
68
- end.to_xml(
69
- save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION |
70
- Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
71
- Nokogiri::XML::Node::SaveOptions::FORMAT
72
- )
73
- domain_volume = env[:machine].provider.driver.connection.volumes.create(
74
- xml: xml,
75
- pool_name: config.storage_pool_name
76
- )
77
- rescue Fog::Errors::Error => e
78
- raise Errors::FogDomainVolumeCreateError,
79
- error_message: e.message
80
- end
81
-
82
- @app.call(env)
83
- end
84
- end
85
- end
86
- end
87
- end
@@ -1,294 +0,0 @@
1
- require 'log4r'
2
- require 'vagrant/util/network_ip'
3
- require 'vagrant/util/scoped_hash_override'
4
-
5
- module VagrantPlugins
6
- module ProviderLibvirt
7
- module Action
8
- # Create network interfaces for domain, before domain is running.
9
- # Networks for connecting those interfaces should be already prepared.
10
- class CreateNetworkInterfaces
11
- include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
12
- include VagrantPlugins::ProviderLibvirt::Util::NetworkUtil
13
- include Vagrant::Util::NetworkIP
14
- include Vagrant::Util::ScopedHashOverride
15
-
16
- def initialize(app, env)
17
- @logger = Log4r::Logger.new('vagrant_libvirt::action::create_network_interfaces')
18
- @management_network_name = env[:machine].provider_config.management_network_name
19
- config = env[:machine].provider_config
20
- @nic_model_type = config.nic_model_type || 'virtio'
21
- @nic_adapter_count = config.nic_adapter_count
22
- @app = app
23
- end
24
-
25
- def call(env)
26
- # Get domain first.
27
- begin
28
- domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
29
- env[:machine].id.to_s
30
- )
31
- rescue => e
32
- raise Errors::NoDomainError,
33
- error_message: e.message
34
- end
35
-
36
- # Setup list of interfaces before creating them.
37
- adapters = []
38
-
39
- # Vagrant gives you adapter 0 by default
40
- # Assign interfaces to slots.
41
- configured_networks(env, @logger).each do |options|
42
- # dont need to create interface for this type
43
- next if options[:iface_type] == :forwarded_port
44
-
45
- # TODO: fill first ifaces with adapter option specified.
46
- if options[:adapter]
47
- if adapters[options[:adapter]]
48
- raise Errors::InterfaceSlotNotAvailable
49
- end
50
-
51
- free_slot = options[:adapter].to_i
52
- @logger.debug "Using specified adapter slot #{free_slot}"
53
- else
54
- free_slot = find_empty(adapters)
55
- @logger.debug "Adapter not specified so found slot #{free_slot}"
56
- raise Errors::InterfaceSlotNotAvailable if free_slot.nil?
57
- end
58
-
59
- # We have slot for interface, fill it with interface configuration.
60
- adapters[free_slot] = options
61
- adapters[free_slot][:network_name] = interface_network(
62
- env[:machine].provider.driver.connection.client, adapters[free_slot]
63
- )
64
- end
65
-
66
- # Create each interface as new domain device.
67
- @macs_per_network = Hash.new(0)
68
- adapters.each_with_index do |iface_configuration, slot_number|
69
- @iface_number = slot_number
70
- @network_name = iface_configuration[:network_name]
71
- @source_options = {
72
- network: @network_name
73
- }
74
- @mac = iface_configuration.fetch(:mac, false)
75
- @model_type = iface_configuration.fetch(:model_type, @nic_model_type)
76
- @driver_name = iface_configuration.fetch(:driver_name, false)
77
- @driver_queues = iface_configuration.fetch(:driver_queues, false)
78
- @device_name = iface_configuration.fetch(:iface_name, false)
79
- template_name = 'interface'
80
- # Configuration for public interfaces which use the macvtap driver
81
- if iface_configuration[:iface_type] == :public_network
82
- @device = iface_configuration.fetch(:dev, 'eth0')
83
- @mode = iface_configuration.fetch(:mode, 'bridge')
84
- @type = iface_configuration.fetch(:type, 'direct')
85
- @model_type = iface_configuration.fetch(:model_type, @nic_model_type)
86
- @driver_name = iface_configuration.fetch(:driver_name, false)
87
- @driver_queues = iface_configuration.fetch(:driver_queues, false)
88
- @portgroup = iface_configuration.fetch(:portgroup, nil)
89
- @network_name = iface_configuration.fetch(:network_name, @network_name)
90
- template_name = 'public_interface'
91
- @logger.info("Setting up public interface using device #{@device} in mode #{@mode}")
92
- @ovs = iface_configuration.fetch(:ovs, false)
93
- @trust_guest_rx_filters = iface_configuration.fetch(:trust_guest_rx_filters, false)
94
- # configuration for udp or tcp tunnel interfaces (p2p conn btwn guest OSes)
95
- elsif iface_configuration.fetch(:tunnel_type, nil)
96
- @type = iface_configuration.fetch(:tunnel_type)
97
- @tunnel_port = iface_configuration.fetch(:tunnel_port, nil)
98
- raise Errors::TunnelPortNotDefined if @tunnel_port.nil?
99
- if @type == 'udp'
100
- # default udp tunnel source to 127.0.0.1
101
- @udp_tunnel={
102
- address: iface_configuration.fetch(:tunnel_local_ip,'127.0.0.1'),
103
- port: iface_configuration.fetch(:tunnel_local_port)
104
- }
105
- end
106
- # default mcast tunnel to 239.255.1.1. Web search says this
107
- # 239.255.x.x is a safe range to use for general use mcast
108
- default_ip = if @type == 'mcast'
109
- '239.255.1.1'
110
- else
111
- '127.0.0.1'
112
- end
113
- @source_options = {
114
- address: iface_configuration.fetch(:tunnel_ip, default_ip),
115
- port: @tunnel_port
116
- }
117
- @tunnel_type = iface_configuration.fetch(:model_type, @nic_model_type)
118
- @driver_name = iface_configuration.fetch(:driver_name, false)
119
- @driver_queues = iface_configuration.fetch(:driver_queues, false)
120
- template_name = 'tunnel_interface'
121
- @logger.info("Setting up #{@type} tunnel interface using #{@tunnel_ip} port #{@tunnel_port}")
122
- end
123
-
124
- message = "Creating network interface eth#{@iface_number}"
125
- message << " connected to network #{@network_name}."
126
- if @mac
127
- @mac = @mac.scan(/(\h{2})/).join(':')
128
- message << " Using MAC address: #{@mac}"
129
- end
130
- @logger.info(message)
131
-
132
- begin
133
- # FIXME: all options for network driver should be hash from Vagrantfile
134
- driver_options = {}
135
- driver_options[:name] = @driver_name if @driver_name
136
- driver_options[:queues] = @driver_queues if @driver_queues
137
- @udp_tunnel ||= {}
138
- xml = if template_name == 'interface' or
139
- template_name == 'tunnel_interface'
140
- interface_xml(@type,
141
- @source_options,
142
- @mac,
143
- @device_name,
144
- @iface_number,
145
- @model_type,
146
- driver_options,
147
- @udp_tunnel)
148
- else
149
- to_xml(template_name)
150
- end
151
- domain.attach_device(xml)
152
- rescue => e
153
- raise Errors::AttachDeviceError,
154
- error_message: e.message
155
- end
156
-
157
- # Re-read the network configuration and grab the MAC address
158
- if iface_configuration[:iface_type] == :public_network
159
- xml = Nokogiri::XML(domain.xml_desc)
160
- source = "@network='#{@network_name}'"
161
- if @type == 'direct'
162
- source = "@dev='#{@device}'"
163
- elsif @portgroup.nil?
164
- source = "@bridge='#{@device}'"
165
- end
166
- if not @mac
167
- macs = xml.xpath("/domain/devices/interface[source[#{source}]]/mac/@address")
168
- @mac = macs[@macs_per_network[source]]
169
- iface_configuration[:mac] = @mac.to_s
170
- end
171
- @macs_per_network[source] += 1
172
- end
173
- end
174
-
175
- # Continue the middleware chain.
176
- @app.call(env)
177
-
178
- if env[:machine].config.vm.box
179
- # Configure interfaces that user requested. Machine should be up and
180
- # running now.
181
- networks_to_configure = []
182
-
183
- adapters.each_with_index do |options, slot_number|
184
- # Skip configuring the management network, which is on the first interface.
185
- # It's used for provisioning and it has to be available during provisioning,
186
- # ifdown command is not acceptable here.
187
- next if slot_number.zero?
188
- next if options[:auto_config] === false
189
- @logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
190
-
191
- network = {
192
- interface: slot_number,
193
- use_dhcp_assigned_default_route: options[:use_dhcp_assigned_default_route],
194
- mac_address: options[:mac]
195
- }
196
-
197
- if options[:ip]
198
- network = {
199
- type: :static,
200
- ip: options[:ip],
201
- netmask: options[:netmask],
202
- gateway: options[:gateway]
203
- }.merge(network)
204
- else
205
- network[:type] = :dhcp
206
- end
207
-
208
- # do not run configure_networks for tcp tunnel interfaces
209
- next if options.fetch(:tunnel_type, nil)
210
-
211
- networks_to_configure << network
212
- end
213
-
214
- env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
215
- env[:machine].guest.capability(
216
- :configure_networks, networks_to_configure
217
- )
218
-
219
- end
220
- end
221
-
222
- private
223
-
224
- def target_dev_name(device_name, type, iface_number)
225
- if device_name
226
- device_name
227
- elsif type == 'netwrok'
228
- "vnet#{iface_number}"
229
- else
230
- # TODO can we use same name vnet#ifnum?
231
- #"tnet#{iface_number}" FIXME plugin vagrant-libvirt trying to create second tnet0 interface
232
- "vnet#{iface_number}"
233
- end
234
- end
235
-
236
- def interface_xml(type, source_options, mac, device_name,
237
- iface_number, model_type, driver_options,
238
- udp_tunnel={})
239
- Nokogiri::XML::Builder.new do |xml|
240
- xml.interface(type: type || 'network') do
241
- xml.source(source_options) do
242
- xml.local(udp_tunnel) if type == 'udp'
243
- end
244
- xml.mac(address: mac) if mac
245
- xml.target(dev: target_dev_name(device_name, type, iface_number))
246
- xml.alias(name: "net#{iface_number}")
247
- xml.model(type: model_type.to_s)
248
- xml.driver(driver_options)
249
- end
250
- end.to_xml(
251
- save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION |
252
- Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
253
- Nokogiri::XML::Node::SaveOptions::FORMAT
254
- )
255
- end
256
-
257
- def find_empty(array, start = 0, stop = @nic_adapter_count)
258
- (start..stop).each do |i|
259
- return i unless array[i]
260
- end
261
- nil
262
- end
263
-
264
- # Return network name according to interface options.
265
- def interface_network(libvirt_client, options)
266
- # no need to get interface network for tcp tunnel config
267
- return 'tunnel_interface' if options.fetch(:tunnel_type, nil)
268
-
269
- if options[:network_name]
270
- @logger.debug 'Found network by name'
271
- return options[:network_name]
272
- end
273
-
274
- # Get list of all (active and inactive) libvirt networks.
275
- available_networks = libvirt_networks(libvirt_client)
276
-
277
- return 'public' if options[:iface_type] == :public_network
278
-
279
- if options[:ip]
280
- address = network_address(options[:ip], options[:netmask])
281
- available_networks.each do |network|
282
- if address == network[:network_address]
283
- @logger.debug 'Found network by ip'
284
- return network[:name]
285
- end
286
- end
287
- end
288
-
289
- raise Errors::NetworkNotAvailableError, network_name: options[:ip]
290
- end
291
- end
292
- end
293
- end
294
- end