vagrant-libvirt 0.0.40 → 0.0.41

Sign up to get free protection for your applications and to get access to all the features.
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