vagrant-libvirt 0.0.30 → 0.0.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +20 -0
  3. data/Gemfile +6 -1
  4. data/README.md +146 -6
  5. data/example_box/Vagrantfile +1 -1
  6. data/example_box/metadata.json +1 -1
  7. data/lib/vagrant-libvirt.rb +3 -15
  8. data/lib/vagrant-libvirt/action.rb +59 -73
  9. data/lib/vagrant-libvirt/action/create_domain.rb +47 -19
  10. data/lib/vagrant-libvirt/action/create_domain_volume.rb +5 -5
  11. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +82 -36
  12. data/lib/vagrant-libvirt/action/create_networks.rb +99 -54
  13. data/lib/vagrant-libvirt/action/destroy_domain.rb +4 -4
  14. data/lib/vagrant-libvirt/action/destroy_networks.rb +2 -2
  15. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  16. data/lib/vagrant-libvirt/action/handle_box_image.rb +25 -5
  17. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +9 -7
  18. data/lib/vagrant-libvirt/action/is_running.rb +1 -1
  19. data/lib/vagrant-libvirt/action/is_suspended.rb +1 -1
  20. data/lib/vagrant-libvirt/action/package_domain.rb +3 -3
  21. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +8 -5
  22. data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +1 -1
  23. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +1 -1
  24. data/lib/vagrant-libvirt/action/read_mac_addresses.rb +1 -1
  25. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +1 -1
  26. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +2 -2
  27. data/lib/vagrant-libvirt/action/resume_domain.rb +1 -1
  28. data/lib/vagrant-libvirt/action/set_boot_order.rb +66 -0
  29. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +3 -2
  30. data/lib/vagrant-libvirt/action/start_domain.rb +1 -1
  31. data/lib/vagrant-libvirt/action/suspend_domain.rb +1 -1
  32. data/lib/vagrant-libvirt/action/wait_till_up.rb +1 -1
  33. data/lib/vagrant-libvirt/cap/mount_p9.rb +2 -1
  34. data/lib/vagrant-libvirt/cap/synced_folder.rb +11 -5
  35. data/lib/vagrant-libvirt/config.rb +44 -5
  36. data/lib/vagrant-libvirt/driver.rb +121 -0
  37. data/lib/vagrant-libvirt/errors.rb +4 -0
  38. data/lib/vagrant-libvirt/plugin.rb +7 -5
  39. data/lib/vagrant-libvirt/provider.rb +54 -12
  40. data/lib/vagrant-libvirt/templates/domain.xml.erb +18 -12
  41. data/lib/vagrant-libvirt/templates/filesystem.xml.erb +1 -1
  42. data/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb +11 -0
  43. data/lib/vagrant-libvirt/util/network_util.rb +11 -1
  44. data/lib/vagrant-libvirt/version.rb +1 -1
  45. data/locales/en.yml +24 -15
  46. data/spec/support/environment_helper.rb +1 -1
  47. data/tools/prepare_redhat_for_box.sh +1 -2
  48. metadata +6 -5
  49. data/lib/vagrant-libvirt/action/connect_libvirt.rb +0 -51
  50. data/lib/vagrant-libvirt/action/read_ssh_info.rb +0 -68
  51. data/lib/vagrant-libvirt/action/read_state.rb +0 -60
@@ -6,7 +6,7 @@ module VagrantPlugins
6
6
  class CreateDomain
7
7
  include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
8
8
 
9
- def initialize(app, env)
9
+ def initialize(app, _env)
10
10
  @logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain')
11
11
  @app = app
12
12
  end
@@ -17,7 +17,7 @@ module VagrantPlugins
17
17
 
18
18
  def _disks_print(disks)
19
19
  disks.collect do |x|
20
- x[:device] + '(' + x[:type] + ',' + x[:size] + ')'
20
+ "#{x[:device]}(#{x[:type]},#{x[:size]})"
21
21
  end.join(', ')
22
22
  end
23
23
 
@@ -33,11 +33,13 @@ module VagrantPlugins
33
33
  @name = env[:domain_name]
34
34
  @cpus = config.cpus.to_i
35
35
  @cpu_mode = config.cpu_mode
36
+ @loader = config.loader
36
37
  @machine_type = config.machine_type
37
38
  @machine_arch = config.machine_arch
38
39
  @disk_bus = config.disk_bus
39
40
  @nested = config.nested
40
41
  @memory_size = config.memory.to_i * 1024
42
+ @management_network_mac = config.management_network_mac
41
43
  @domain_volume_cache = config.volume_cache
42
44
  @kernel = config.kernel
43
45
  @cmd_line = config.cmd_line
@@ -49,12 +51,12 @@ module VagrantPlugins
49
51
  @graphics_passwd = if config.graphics_passwd.to_s.empty?
50
52
  ''
51
53
  else
52
- "passwd='#{config.graphics_passwd.to_s}'"
54
+ "passwd='#{config.graphics_passwd}'"
53
55
  end
54
56
  @video_type = config.video_type
55
57
  @video_vram = config.video_vram
56
58
  @keymap = config.keymap
57
-
59
+
58
60
  # Boot order
59
61
  @boot_order = config.boot_order
60
62
 
@@ -63,19 +65,37 @@ module VagrantPlugins
63
65
  @disks = config.disks
64
66
  @cdroms = config.cdroms
65
67
 
68
+ # Input
69
+ @inputs = config.inputs
70
+
66
71
  config = env[:machine].provider_config
67
72
  @domain_type = config.driver
68
73
 
69
74
  @os_type = 'hvm'
70
75
 
71
- # Get path to domain image.
72
- domain_volume = ProviderLibvirt::Util::Collection.find_matching(
73
- env[:libvirt_compute].volumes.all, "#{@name}.img")
74
- raise Errors::DomainVolumeExists if domain_volume.nil?
75
- @domain_volume_path = domain_volume.path
76
+ # Get path to domain image from the storage pool selected if we have a box.
77
+ if env[:machine].box
78
+ actual_volumes =
79
+ env[:machine].provider.driver.connection.volumes.all.select do |x|
80
+ x.pool_name == @storage_pool_name
81
+ end
82
+ domain_volume = ProviderLibvirt::Util::Collection.find_matching(
83
+ actual_volumes,"#{@name}.img")
84
+ raise Errors::DomainVolumeExists if domain_volume.nil?
85
+ @domain_volume_path = domain_volume.path
86
+ end
76
87
 
88
+ # If we have a box, take the path from the domain volume and set our storage_prefix.
89
+ # If not, we dump the storage pool xml to get its defined path.
77
90
  # the default storage prefix is typically: /var/lib/libvirt/images/
78
- storage_prefix = File.dirname(@domain_volume_path) + '/' # steal
91
+ if env[:machine].box
92
+ storage_prefix = File.dirname(@domain_volume_path) + '/' # steal
93
+ else
94
+ storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name)
95
+ raise Errors::NoStoragePool if storage_pool.nil?
96
+ xml = Nokogiri::XML(storage_pool.xml_desc)
97
+ storage_prefix = xml.xpath("/pool/target/path").inner_text.to_s + '/'
98
+ end
79
99
 
80
100
  @disks.each do |disk|
81
101
  disk[:path] ||= _disk_name(@name, disk)
@@ -88,11 +108,13 @@ module VagrantPlugins
88
108
 
89
109
  disk[:absolute_path] = storage_prefix + disk[:path]
90
110
 
91
- if env[:libvirt_compute].volumes.all.select {|x| x.name == disk[:name] }.empty?
111
+ if env[:machine].provider.driver.connection.volumes.select do |x|
112
+ x.name == disk[:name] && x.pool_name == @storage_pool_name
113
+ end.empty?
92
114
  # make the disk. equivalent to:
93
115
  # qemu-img create -f qcow2 <path> 5g
94
116
  begin
95
- env[:libvirt_compute].volumes.create(
117
+ env[:machine].provider.driver.connection.volumes.create(
96
118
  name: disk[:name],
97
119
  format_type: disk[:type],
98
120
  path: disk[:absolute_path],
@@ -114,9 +136,13 @@ module VagrantPlugins
114
136
  env[:ui].info(" -- Domain type: #{@domain_type}")
115
137
  env[:ui].info(" -- Cpus: #{@cpus}")
116
138
  env[:ui].info(" -- Memory: #{@memory_size / 1024}M")
117
- env[:ui].info(" -- Base box: #{env[:machine].box.name}")
139
+ env[:ui].info(" -- Management MAC: #{@management_network_mac}")
140
+ env[:ui].info(" -- Loader: #{@loader}")
141
+ if env[:machine].box
142
+ env[:ui].info(" -- Base box: #{env[:machine].box.name}")
143
+ end
118
144
  env[:ui].info(" -- Storage pool: #{@storage_pool_name}")
119
- env[:ui].info(" -- Image: #{@domain_volume_path}")
145
+ env[:ui].info(" -- Image: #{@domain_volume_path} (#{env[:box_virtual_size]}G)")
120
146
  env[:ui].info(" -- Volume Cache: #{@domain_volume_cache}")
121
147
  env[:ui].info(" -- Kernel: #{@kernel}")
122
148
  env[:ui].info(" -- Initrd: #{@initrd}")
@@ -127,7 +153,7 @@ module VagrantPlugins
127
153
  env[:ui].info(" -- Video Type: #{@video_type}")
128
154
  env[:ui].info(" -- Video VRAM: #{@video_vram}")
129
155
  env[:ui].info(" -- Keymap: #{@keymap}")
130
-
156
+
131
157
  @boot_order.each do |device|
132
158
  env[:ui].info(" -- Boot device: #{device}")
133
159
  end
@@ -138,8 +164,8 @@ module VagrantPlugins
138
164
 
139
165
  @disks.each do |disk|
140
166
  msg = " -- Disk(#{disk[:device]}): #{disk[:absolute_path]}"
141
- msg += " (shared. Remove only manualy)" if disk[:allow_existing]
142
- msg += " Not created - using existed." if disk[:preexisting]
167
+ msg += ' (shared. Remove only manually)' if disk[:allow_existing]
168
+ msg += ' Not created - using existed.' if disk[:preexisting]
143
169
  env[:ui].info(msg)
144
170
  end
145
171
 
@@ -150,14 +176,16 @@ module VagrantPlugins
150
176
  @cdroms.each do |cdrom|
151
177
  env[:ui].info(" -- CDROM(#{cdrom[:dev]}): #{cdrom[:path]}")
152
178
  end
153
-
179
+ @inputs.each do |input|
180
+ env[:ui].info(" -- INPUT : type=#{input[:type]}, bus=#{input[:bus]}")
181
+ end
154
182
  env[:ui].info(" -- Command line : #{@cmd_line}")
155
183
 
156
184
  # Create libvirt domain.
157
185
  # Is there a way to tell fog to create new domain with already
158
186
  # existing volume? Use domain creation from template..
159
187
  begin
160
- server = env[:libvirt_compute].servers.create(
188
+ server = env[:machine].provider.driver.connection.servers.create(
161
189
  xml: to_xml('domain'))
162
190
  rescue Fog::Errors::Error => e
163
191
  raise Errors::FogCreateServerError, error_message: e.message
@@ -26,21 +26,21 @@ module VagrantPlugins
26
26
 
27
27
  # Verify the volume doesn't exist already.
28
28
  domain_volume = ProviderLibvirt::Util::Collection.find_matching(
29
- env[:libvirt_compute].volumes.all, @name)
29
+ env[:machine].provider.driver.connection.volumes.all, @name)
30
30
  raise Errors::DomainVolumeExists if domain_volume
31
31
 
32
32
  # Get path to backing image - box volume.
33
33
  box_volume = ProviderLibvirt::Util::Collection.find_matching(
34
- env[:libvirt_compute].volumes.all, env[:box_volume_name])
34
+ env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name])
35
35
  @backing_file = box_volume.path
36
36
 
37
- # Virtual size of image. Same as box image size.
38
- @capacity = env[:machine].box.metadata['virtual_size'] #G
37
+ # Virtual size of image. Take value worked out by HandleBoxImage
38
+ @capacity = env[:box_virtual_size] #G
39
39
 
40
40
  # Create new volume from xml template. Fog currently doesn't support
41
41
  # volume snapshots directly.
42
42
  begin
43
- domain_volume = env[:libvirt_compute].volumes.create(
43
+ domain_volume = env[:machine].provider.driver.connection.volumes.create(
44
44
  :xml => to_xml('volume_snapshot'),
45
45
  :pool_name => config.storage_pool_name)
46
46
  rescue Fog::Errors::Error => e
@@ -19,13 +19,14 @@ module VagrantPlugins
19
19
  @management_network_name = env[:machine].provider_config.management_network_name
20
20
  config = env[:machine].provider_config
21
21
  @nic_model_type = config.nic_model_type
22
+ @nic_adapter_count = config.nic_adapter_count
22
23
  @app = app
23
24
  end
24
25
 
25
26
  def call(env)
26
27
  # Get domain first.
27
28
  begin
28
- domain = env[:libvirt_compute].client.lookup_domain_by_uuid(
29
+ domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
29
30
  env[:machine].id.to_s)
30
31
  rescue => e
31
32
  raise Errors::NoDomainError,
@@ -36,7 +37,6 @@ module VagrantPlugins
36
37
  adapters = []
37
38
 
38
39
  # Vagrant gives you adapter 0 by default
39
-
40
40
  # Assign interfaces to slots.
41
41
  configured_networks(env, @logger).each do |options|
42
42
 
@@ -60,7 +60,7 @@ module VagrantPlugins
60
60
  # We have slot for interface, fill it with interface configuration.
61
61
  adapters[free_slot] = options
62
62
  adapters[free_slot][:network_name] = interface_network(
63
- env[:libvirt_compute].client, adapters[free_slot])
63
+ env[:machine].provider.driver.connection.client, adapters[free_slot])
64
64
  end
65
65
 
66
66
  # Create each interface as new domain device.
@@ -70,7 +70,6 @@ module VagrantPlugins
70
70
  @mac = iface_configuration.fetch(:mac, false)
71
71
  @model_type = iface_configuration.fetch(:model_type, @nic_model_type)
72
72
  template_name = 'interface'
73
-
74
73
  # Configuration for public interfaces which use the macvtap driver
75
74
  if iface_configuration[:iface_type] == :public_network
76
75
  @device = iface_configuration.fetch(:dev, 'eth0')
@@ -80,8 +79,30 @@ module VagrantPlugins
80
79
  template_name = 'public_interface'
81
80
  @logger.info("Setting up public interface using device #{@device} in mode #{@mode}")
82
81
  @ovs = iface_configuration.fetch(:ovs, false)
82
+ # configuration for udp or tcp tunnel interfaces (p2p conn btwn guest OSes)
83
+ elsif iface_configuration.fetch(:tunnel_type, nil)
84
+ @type = iface_configuration.fetch(:tunnel_type)
85
+ @tunnel_port = iface_configuration.fetch(:tunnel_port, nil)
86
+ raise Errors::TunnelPortNotDefined if @tunnel_port.nil?
87
+ if @type == 'udp'
88
+ # default udp tunnel source to 127.0.0.1
89
+ @udp_tunnel_local_ip = iface_configuration.fetch(:tunnel_local_ip, '127.0.0.1')
90
+ @udp_tunnel_local_port = iface_configuration.fetch(:tunnel_local_port)
91
+ end
92
+ # default mcast tunnel to 239.255.1.1. Web search says this
93
+ # 239.255.x.x is a safe range to use for general use mcast
94
+ if @type == 'mcast'
95
+ default_ip = '239.255.1.1'
96
+ else
97
+ default_ip = '127.0.0.1'
98
+ end
99
+ @tunnel_ip = iface_configuration.fetch(:tunnel_address, default_ip)
100
+ @model_type = iface_configuration.fetch(:model_type, @nic_model_type)
101
+ template_name = 'tunnel_interface'
102
+ @logger.info("Setting up #{@type} tunnel interface using #{@tunnel_ip} port #{@tunnel_port}")
83
103
  end
84
104
 
105
+
85
106
  message = "Creating network interface eth#{@iface_number}"
86
107
  message << " connected to network #{@network_name}."
87
108
  if @mac
@@ -96,58 +117,83 @@ module VagrantPlugins
96
117
  raise Errors::AttachDeviceError,
97
118
  :error_message => e.message
98
119
  end
120
+
121
+ # Re-read the network configuration and grab the MAC address
122
+ unless @mac
123
+ xml = Nokogiri::XML(domain.xml_desc)
124
+ if iface_configuration[:iface_type] == :public_network
125
+ if @type == 'direct'
126
+ @mac = xml.xpath("/domain/devices/interface[source[@dev='#{@device}']]/mac/@address")
127
+ else
128
+ @mac = xml.xpath("/domain/devices/interface[source[@bridge='#{@device}']]/mac/@address")
129
+ end
130
+ else
131
+ @mac = xml.xpath("/domain/devices/interface[source[@network='#{@network_name}']]/mac/@address")
132
+ end
133
+ iface_configuration[:mac] = @mac.to_s
134
+ end
99
135
  end
100
136
 
101
137
  # Continue the middleware chain.
102
138
  @app.call(env)
103
139
 
104
- # Configure interfaces that user requested. Machine should be up and
105
- # running now.
106
- networks_to_configure = []
107
-
108
- adapters.each_with_index do |options, slot_number|
109
- # Skip configuring the management network, which is on the first interface.
110
- # It's used for provisioning and it has to be available during provisioning,
111
- # ifdown command is not acceptable here.
112
- next if slot_number == 0
113
- next if options[:auto_config] === false
114
- @logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
115
-
116
- network = {
117
- :interface => slot_number,
118
- :use_dhcp_assigned_default_route => options[:use_dhcp_assigned_default_route],
119
- #:mac => ...,
120
- }
121
-
122
- if options[:ip]
140
+
141
+ if env[:machine].box
142
+ # Configure interfaces that user requested. Machine should be up and
143
+ # running now.
144
+ networks_to_configure = []
145
+
146
+ adapters.each_with_index do |options, slot_number|
147
+ # Skip configuring the management network, which is on the first interface.
148
+ # It's used for provisioning and it has to be available during provisioning,
149
+ # ifdown command is not acceptable here.
150
+ next if slot_number == 0
151
+ next if options[:auto_config] === false
152
+ @logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
153
+
123
154
  network = {
124
- :type => :static,
125
- :ip => options[:ip],
126
- :netmask => options[:netmask],
127
- }.merge(network)
128
- else
129
- network[:type] = :dhcp
155
+ :interface => slot_number,
156
+ :use_dhcp_assigned_default_route => options[:use_dhcp_assigned_default_route],
157
+ :mac_address => options[:mac],
158
+ }
159
+
160
+ if options[:ip]
161
+ network = {
162
+ :type => :static,
163
+ :ip => options[:ip],
164
+ :netmask => options[:netmask],
165
+ }.merge(network)
166
+ else
167
+ network[:type] = :dhcp
168
+ end
169
+
170
+ # do not run configure_networks for tcp tunnel interfaces
171
+ next if options.fetch(:tunnel_type, nil)
172
+
173
+ networks_to_configure << network
130
174
  end
131
175
 
132
- networks_to_configure << network
133
- end
176
+ env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
177
+ env[:machine].guest.capability(
178
+ :configure_networks, networks_to_configure)
134
179
 
135
- env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
136
- env[:machine].guest.capability(
137
- :configure_networks, networks_to_configure)
180
+ end
138
181
  end
139
182
 
140
183
  private
141
184
 
142
- def find_empty(array, start=0, stop=8)
185
+ def find_empty(array, start=0, stop=@nic_adapter_count)
143
186
  (start..stop).each do |i|
144
- return i if !array[i]
187
+ return i unless array[i]
145
188
  end
146
189
  return nil
147
190
  end
148
191
 
149
192
  # Return network name according to interface options.
150
193
  def interface_network(libvirt_client, options)
194
+ # no need to get interface network for tcp tunnel config
195
+ return 'tunnel_interface' if options.fetch(:tunnel_type, nil)
196
+
151
197
  if options[:network_name]
152
198
  @logger.debug "Found network by name"
153
199
  return options[:network_name]
@@ -23,7 +23,7 @@ module VagrantPlugins
23
23
 
24
24
  @available_networks = []
25
25
  @options = {}
26
- @libvirt_client = env[:libvirt_compute].client
26
+ @libvirt_client = env[:machine].provider.driver.connection.client
27
27
  end
28
28
 
29
29
  def call(env)
@@ -35,7 +35,8 @@ module VagrantPlugins
35
35
  # available, create it if possible. Otherwise raise an error.
36
36
  configured_networks(env, @logger).each do |options|
37
37
  # Only need to create private networks
38
- next if options[:iface_type] != :private_network
38
+ next if options[:iface_type] != :private_network ||
39
+ options.fetch(:tunnel_type, nil)
39
40
  @logger.debug "Searching for network with options #{options}"
40
41
 
41
42
  # should fix other methods so this doesn't have to be instance var
@@ -45,7 +46,7 @@ module VagrantPlugins
45
46
  # list is used throughout this class and should be easier to
46
47
  # process than libvirt API calls.
47
48
  @available_networks = libvirt_networks(
48
- env[:libvirt_compute].client)
49
+ env[:machine].provider.driver.connection.client)
49
50
 
50
51
  # Prepare a hash describing network for this specific interface.
51
52
  @interface_network = {
@@ -62,15 +63,16 @@ module VagrantPlugins
62
63
 
63
64
  if @options[:ip]
64
65
  handle_ip_option(env)
65
- # in vagrant 1.2.3 and later it is not possible to take this branch
66
- # because cannot have name without ip
67
- # https://github.com/mitchellh/vagrant/commit/cf2f6da4dbcb4f57c9cdb3b94dcd0bba62c5f5fd
66
+ elsif @options[:type].to_s == 'dhcp'
67
+ handle_dhcp_private_network(env)
68
68
  elsif @options[:network_name]
69
- handle_network_name_option
69
+ handle_network_name_option(env)
70
+ else
71
+ raise Errors::CreateNetworkError, error_message: @options
70
72
  end
71
73
 
72
- autostart_network if !@interface_network[:autostart]
73
- activate_network if !@interface_network[:active]
74
+ autostart_network if @interface_network[:autostart]
75
+ activate_network unless @interface_network[:active]
74
76
  end
75
77
  end
76
78
 
@@ -79,22 +81,21 @@ module VagrantPlugins
79
81
 
80
82
  private
81
83
 
84
+ def lookup_network_by_ip(ip)
85
+ @logger.debug "looking up network with ip == #{ip}"
86
+ @available_networks.find { |network| network[:network_address] == ip }
87
+ end
88
+
82
89
  # Return hash of network for specified name, or nil if not found.
83
90
  def lookup_network_by_name(network_name)
84
91
  @logger.debug "looking up network named #{network_name}"
85
- @available_networks.each do |network|
86
- return network if network[:name] == network_name
87
- end
88
- nil
92
+ @available_networks.find { |network| network[:name] == network_name }
89
93
  end
90
94
 
91
95
  # Return hash of network for specified bridge, or nil if not found.
92
96
  def lookup_bridge_by_name(bridge_name)
93
97
  @logger.debug "looking up bridge named #{bridge_name}"
94
- @available_networks.each do |network|
95
- return network if network[:bridge_name] == bridge_name
96
- end
97
- nil
98
+ @available_networks.find { |network| network[:bridge_name] == bridge_name }
98
99
  end
99
100
 
100
101
  # Throw an error if dhcp setting for an existing network does not
@@ -114,28 +115,30 @@ module VagrantPlugins
114
115
  # Handle only situations, when ip is specified. Variables @options and
115
116
  # @available_networks should be filled before calling this function.
116
117
  def handle_ip_option(env)
117
- return if !@options[:ip]
118
+ return unless @options[:ip]
119
+ net_address = nil
120
+ unless @options[:forward_mode] == 'veryisolated'
121
+ net_address = network_address(@options[:ip], @options[:netmask])
122
+
123
+ # Set IP address of network (actually bridge). It will be used as
124
+ # gateway address for machines connected to this network.
125
+ @interface_network[:ip_address] = get_host_ip_addr(net_address)
126
+ end
118
127
 
119
- net_address = network_address(@options[:ip], @options[:netmask])
120
128
  @interface_network[:network_address] = net_address
121
129
 
122
- # Set IP address of network (actually bridge). It will be used as
123
- # gateway address for machines connected to this network.
124
- net = IPAddr.new(net_address)
125
- # Default to first address (after network name)
126
- @interface_network[:ip_address] = @options[:host_ip].nil? ? net.to_range.begin.succ : IPAddr.new(@options[:host_ip])
127
-
128
- # Is there an available network matching to configured ip
129
- # address?
130
- @available_networks.each do |available_network|
131
- if available_network[:network_address] == \
132
- @interface_network[:network_address]
133
- @interface_network = available_network
134
- @logger.debug "found existing network by ip, values are"
135
- @logger.debug @interface_network
136
- break
137
- end
130
+ # if network is veryisolated, search by name
131
+ if @options[:libvirt__forward_mode] == "veryisolated"
132
+ network = lookup_network_by_name(@options[:network_name])
133
+ elsif net_address
134
+ # otherwise, search by ip (if set)
135
+ network = lookup_network_by_ip(net_address)
136
+ else
137
+ # leaving this here to mimic prior behavior. If we get
138
+ # here, something's probably broken.
139
+ network = lookup_network_by_name(@options[:network_name])
138
140
  end
141
+ @interface_network = network if network
139
142
 
140
143
  if @interface_network[:created]
141
144
  verify_dhcp
@@ -167,7 +170,7 @@ module VagrantPlugins
167
170
  end
168
171
 
169
172
  # Do we need to create new network?
170
- if !@interface_network[:created]
173
+ unless @interface_network[:created]
171
174
 
172
175
  # TODO: stop after some loops. Don't create infinite loops.
173
176
 
@@ -188,17 +191,7 @@ module VagrantPlugins
188
191
  end
189
192
 
190
193
  # Generate a unique name for network bridge.
191
- count = 0
192
- while @interface_network[:bridge_name].nil?
193
- @logger.debug "generating name for bridge"
194
- bridge_name = 'virbr'
195
- bridge_name << count.to_s
196
- count += 1
197
-
198
- next if lookup_bridge_by_name(bridge_name)
199
-
200
- @interface_network[:bridge_name] = bridge_name
201
- end
194
+ @interface_network[:bridge_name] = generate_bridge_name
202
195
 
203
196
  # Create a private network.
204
197
  create_private_network(env)
@@ -208,16 +201,68 @@ module VagrantPlugins
208
201
  # Handle network_name option, if ip was not specified. Variables
209
202
  # @options and @available_networks should be filled before calling this
210
203
  # function.
211
- def handle_network_name_option
212
- return if @options[:ip] || !@options[:network_name]
204
+ def handle_network_name_option(env)
205
+ return if @options[:ip] || \
206
+ !@options[:network_name] || \
207
+ !@options[:libvirt__forward_mode] == "veryisolated"
208
+
209
+ network = lookup_network_by_name(@options[:network_name])
210
+ @interface_network = network if network
213
211
 
214
- @interface_network = lookup_network_by_name(@options[:network_name])
215
- if !@interface_network
212
+ # if this interface has a network address, something's wrong.
213
+ if @interface_network[:network_address]
216
214
  raise Errors::NetworkNotAvailableError,
217
215
  network_name: @options[:network_name]
218
- else
219
- verify_dhcp
220
216
  end
217
+
218
+ # Do we need to create new network?
219
+ unless @interface_network[:created]
220
+ @interface_network[:name] = @options[:network_name]
221
+
222
+ # Generate a unique name for network bridge.
223
+ @interface_network[:bridge_name] = generate_bridge_name
224
+
225
+ # Create a private network.
226
+ create_private_network(env)
227
+ end
228
+ end
229
+
230
+ def handle_dhcp_private_network(env)
231
+ net_address = '172.28.128.0'
232
+ network = lookup_network_by_ip(net_address)
233
+ @interface_network = network if network
234
+
235
+ # Do we need to create new network?
236
+ unless @interface_network[:created]
237
+ @interface_network[:name] = 'vagrant-private-dhcp'
238
+ @interface_network[:network_address] = net_address
239
+
240
+ # Set IP address of network (actually bridge). It will be used as
241
+ # gateway address for machines connected to this network.
242
+ @interface_network[:ip_address] = get_host_ip_addr(net_address)
243
+
244
+ # Generate a unique name for network bridge.
245
+ @interface_network[:bridge_name] = generate_bridge_name
246
+
247
+ # Create a private network.
248
+ create_private_network(env)
249
+ end
250
+ end
251
+
252
+ # Return provided address or first address of network otherwise
253
+ def get_host_ip_addr(network)
254
+ @options[:host_ip] ? IPAddr.new(@options[:host_ip]) : IPAddr.new(network).succ
255
+ end
256
+
257
+ # Return the first available virbr interface name
258
+ def generate_bridge_name
259
+ @logger.debug "generating name for bridge"
260
+ count = 0
261
+ while lookup_bridge_by_name(bridge_name = "virbr#{count}")
262
+ count += 1
263
+ end
264
+ @logger.debug "found available bridge name #{bridge_name}"
265
+ bridge_name
221
266
  end
222
267
 
223
268
  def create_private_network(env)
@@ -235,7 +280,7 @@ module VagrantPlugins
235
280
  # Find out DHCP addresses pool range.
236
281
  network_address = "#{@interface_network[:network_address]}/"
237
282
  network_address << "#{@interface_network[:netmask]}"
238
- net = IPAddr.new(network_address)
283
+ net = @interface_network[:network_address] ? IPAddr.new(network_address) : nil
239
284
 
240
285
  # First is address of network, second is gateway (by default).
241
286
  # So start the range two addresses after network address by default.