vagrant-libvirt 0.0.42 → 0.2.1

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 (60) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +393 -147
  3. data/lib/vagrant-libvirt/action.rb +3 -2
  4. data/lib/vagrant-libvirt/action/create_domain.rb +87 -37
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +19 -14
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +9 -5
  7. data/lib/vagrant-libvirt/action/create_networks.rb +7 -2
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  9. data/lib/vagrant-libvirt/action/destroy_networks.rb +5 -0
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +10 -8
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +26 -15
  13. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +9 -4
  14. data/lib/vagrant-libvirt/action/package_domain.rb +58 -12
  15. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
  16. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +19 -9
  17. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
  18. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
  19. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
  20. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
  21. data/lib/vagrant-libvirt/action/start_domain.rb +2 -2
  22. data/lib/vagrant-libvirt/action/wait_till_up.rb +31 -16
  23. data/lib/vagrant-libvirt/cap/public_address.rb +16 -0
  24. data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
  25. data/lib/vagrant-libvirt/config.rb +177 -29
  26. data/lib/vagrant-libvirt/driver.rb +31 -2
  27. data/lib/vagrant-libvirt/errors.rb +5 -1
  28. data/lib/vagrant-libvirt/plugin.rb +7 -2
  29. data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +3 -3
  30. data/lib/vagrant-libvirt/templates/domain.xml.erb +48 -8
  31. data/lib/vagrant-libvirt/util.rb +1 -0
  32. data/lib/vagrant-libvirt/util/erb_template.rb +6 -7
  33. data/lib/vagrant-libvirt/util/network_util.rb +33 -13
  34. data/lib/vagrant-libvirt/util/nfs.rb +17 -0
  35. data/lib/vagrant-libvirt/util/storage_util.rb +27 -0
  36. data/lib/vagrant-libvirt/version.rb +1 -1
  37. data/locales/en.yml +8 -4
  38. data/spec/support/environment_helper.rb +1 -1
  39. data/spec/support/libvirt_context.rb +1 -1
  40. data/spec/support/sharedcontext.rb +2 -2
  41. data/spec/unit/action/destroy_domain_spec.rb +2 -2
  42. data/spec/unit/action/set_name_of_domain_spec.rb +3 -3
  43. data/spec/unit/config_spec.rb +173 -0
  44. data/spec/unit/templates/domain_all_settings.xml +20 -4
  45. data/spec/unit/templates/domain_custom_cpu_model.xml +48 -0
  46. data/spec/unit/templates/domain_defaults.xml +2 -0
  47. data/spec/unit/templates/domain_spec.rb +26 -2
  48. metadata +24 -32
  49. data/.coveralls.yml +0 -1
  50. data/.github/issue_template.md +0 -37
  51. data/.gitignore +0 -21
  52. data/.travis.yml +0 -24
  53. data/Gemfile +0 -26
  54. data/Rakefile +0 -8
  55. data/example_box/README.md +0 -29
  56. data/example_box/Vagrantfile +0 -60
  57. data/example_box/metadata.json +0 -5
  58. data/tools/create_box.sh +0 -130
  59. data/tools/prepare_redhat_for_box.sh +0 -119
  60. data/vagrant-libvirt.gemspec +0 -54
@@ -8,7 +8,7 @@ module VagrantPlugins
8
8
  include Vagrant::Action::Builtin
9
9
  @logger = Log4r::Logger.new('vagrant_libvirt::action')
10
10
 
11
- # remove image from libvirt storage pool
11
+ # remove image from Libvirt storage pool
12
12
  def self.remove_libvirt_image
13
13
  Vagrant::Action::Builder.new.tap do |b|
14
14
  b.use RemoveLibvirtImage
@@ -19,6 +19,7 @@ module VagrantPlugins
19
19
  def self.action_up
20
20
  Vagrant::Action::Builder.new.tap do |b|
21
21
  b.use ConfigValidate
22
+ b.use BoxCheckOutdated
22
23
  b.use Call, IsCreated do |env, b2|
23
24
  # Create VM if not yet created.
24
25
  if !env[:result]
@@ -186,7 +187,7 @@ module VagrantPlugins
186
187
  b2.use Call, DestroyConfirm do |env2, b3|
187
188
  if env2[:result]
188
189
  b3.use ClearForwardedPorts
189
- # b3.use PruneNFSExports
190
+ b3.use PruneNFSExports
190
191
  b3.use DestroyDomain
191
192
  b3.use DestroyNetworks
192
193
  b3.use ProvisionerCleanup
@@ -31,16 +31,23 @@ module VagrantPlugins
31
31
 
32
32
  # Gather some info about domain
33
33
  @name = env[:domain_name]
34
+ @title = config.title
35
+ @description = config.description
34
36
  @uuid = config.uuid
35
37
  @cpus = config.cpus.to_i
38
+ @cpuset = config.cpuset
36
39
  @cpu_features = config.cpu_features
37
40
  @cpu_topology = config.cpu_topology
41
+ @nodeset = config.nodeset
38
42
  @features = config.features
43
+ @features_hyperv = config.features_hyperv
44
+ @shares = config.shares
39
45
  @cpu_mode = config.cpu_mode
40
46
  @cpu_model = config.cpu_model
41
47
  @cpu_fallback = config.cpu_fallback
42
48
  @numa_nodes = config.numa_nodes
43
49
  @loader = config.loader
50
+ @nvram = config.nvram
44
51
  @machine_type = config.machine_type
45
52
  @machine_arch = config.machine_arch
46
53
  @disk_bus = config.disk_bus
@@ -79,6 +86,7 @@ module VagrantPlugins
79
86
 
80
87
  # Storage
81
88
  @storage_pool_name = config.storage_pool_name
89
+ @snapshot_pool_name = config.snapshot_pool_name
82
90
  @disks = config.disks
83
91
  @cdroms = config.cdroms
84
92
 
@@ -94,6 +102,9 @@ module VagrantPlugins
94
102
  # Watchdog device
95
103
  @watchdog_dev = config.watchdog_dev
96
104
 
105
+ # USB controller
106
+ @usbctl_dev = config.usbctl_dev
107
+
97
108
  # USB device passthrough
98
109
  @usbs = config.usbs
99
110
 
@@ -101,6 +112,12 @@ module VagrantPlugins
101
112
  @redirdevs = config.redirdevs
102
113
  @redirfilters = config.redirfilters
103
114
 
115
+ # Additional QEMU commandline arguments
116
+ @qemu_args = config.qemu_args
117
+
118
+ # Additional QEMU commandline environment variables
119
+ @qemu_env = config.qemu_env
120
+
104
121
  # smartcard device
105
122
  @smartcard_dev = config.smartcard_dev
106
123
 
@@ -114,13 +131,15 @@ module VagrantPlugins
114
131
 
115
132
  # Get path to domain image from the storage pool selected if we have a box.
116
133
  if env[:machine].config.vm.box
117
- actual_volumes =
118
- env[:machine].provider.driver.connection.volumes.all.select do |x|
119
- x.pool_name == @storage_pool_name
120
- end
121
- domain_volume = ProviderLibvirt::Util::Collection.find_matching(
122
- actual_volumes, "#{@name}.img"
123
- )
134
+ if @snapshot_pool_name != @storage_pool_name
135
+ pool_name = @snapshot_pool_name
136
+ else
137
+ pool_name = @storage_pool_name
138
+ end
139
+ @logger.debug "Search for volume in pool: #{pool_name}"
140
+ domain_volume = env[:machine].provider.driver.connection.volumes.all(
141
+ name: "#{@name}.img"
142
+ ).find { |x| x.pool_name == pool_name }
124
143
  raise Errors::DomainVolumeExists if domain_volume.nil?
125
144
  @domain_volume_path = domain_volume.path
126
145
  end
@@ -128,13 +147,15 @@ module VagrantPlugins
128
147
  # If we have a box, take the path from the domain volume and set our storage_prefix.
129
148
  # If not, we dump the storage pool xml to get its defined path.
130
149
  # the default storage prefix is typically: /var/lib/libvirt/images/
131
- if env[:machine].config.vm.box
132
- storage_prefix = File.dirname(@domain_volume_path) + '/' # steal
133
- else
134
- storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name)
135
- raise Errors::NoStoragePool if storage_pool.nil?
136
- xml = Nokogiri::XML(storage_pool.xml_desc)
137
- storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/'
150
+ if !config.qemu_use_session
151
+ if env[:machine].config.vm.box
152
+ storage_prefix = File.dirname(@domain_volume_path) + '/' # steal
153
+ else
154
+ storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name)
155
+ raise Errors::NoStoragePool if storage_pool.nil?
156
+ xml = Nokogiri::XML(storage_pool.xml_desc)
157
+ storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/'
158
+ end
138
159
  end
139
160
 
140
161
  @disks.each do |disk|
@@ -148,51 +169,67 @@ module VagrantPlugins
148
169
 
149
170
  disk[:absolute_path] = storage_prefix + disk[:path]
150
171
 
151
- if env[:machine].provider.driver.connection.volumes.select do |x|
152
- x.name == disk[:name] && x.pool_name == @storage_pool_name
153
- end.empty?
154
- # make the disk. equivalent to:
155
- # qemu-img create -f qcow2 <path> 5g
156
- begin
157
- env[:machine].provider.driver.connection.volumes.create(
158
- name: disk[:name],
159
- format_type: disk[:type],
160
- path: disk[:absolute_path],
161
- capacity: disk[:size],
162
- #:allocation => ?,
163
- pool_name: @storage_pool_name
164
- )
165
- rescue Fog::Errors::Error => e
172
+ # make the disk. equivalent to:
173
+ # qemu-img create -f qcow2 <path> 5g
174
+ begin
175
+ env[:machine].provider.driver.connection.volumes.create(
176
+ name: disk[:name],
177
+ format_type: disk[:type],
178
+ path: disk[:absolute_path],
179
+ capacity: disk[:size],
180
+ #:allocation => ?,
181
+ pool_name: @storage_pool_name
182
+ )
183
+ rescue Libvirt::Error => e
184
+ # It is hard to believe that e contains just a string
185
+ # and no useful error code!
186
+ msg = "Call to virStorageVolCreateXML failed: " +
187
+ "storage volume '#{disk[:path]}' exists already"
188
+ if e.message == msg and disk[:allow_existing]
189
+ disk[:preexisting] = true
190
+ else
166
191
  raise Errors::FogDomainVolumeCreateError,
167
192
  error_message: e.message
168
193
  end
169
- else
170
- disk[:preexisting] = true
171
194
  end
172
195
  end
173
196
 
174
197
  # Output the settings we're going to use to the user
175
198
  env[:ui].info(I18n.t('vagrant_libvirt.creating_domain'))
176
199
  env[:ui].info(" -- Name: #{@name}")
200
+ env[:ui].info(" -- Title: #{@title}") if @title != ''
201
+ env[:ui].info(" -- Description: #{@description}") if @description != ''
177
202
  env[:ui].info(" -- Forced UUID: #{@uuid}") if @uuid != ''
178
203
  env[:ui].info(" -- Domain type: #{@domain_type}")
179
204
  env[:ui].info(" -- Cpus: #{@cpus}")
205
+ unless @cpuset.nil?
206
+ env[:ui].info(" -- Cpuset: #{@cpuset}")
207
+ end
180
208
  if not @cpu_topology.empty?
181
209
  env[:ui].info(" -- CPU topology: sockets=#{@cpu_topology[:sockets]}, cores=#{@cpu_topology[:cores]}, threads=#{@cpu_topology[:threads]}")
182
210
  end
183
- env[:ui].info("")
184
211
  @cpu_features.each do |cpu_feature|
185
212
  env[:ui].info(" -- CPU Feature: name=#{cpu_feature[:name]}, policy=#{cpu_feature[:policy]}")
186
213
  end
187
214
  @features.each do |feature|
188
215
  env[:ui].info(" -- Feature: #{feature}")
189
216
  end
217
+ @features_hyperv.each do |feature|
218
+ env[:ui].info(" -- Feature (HyperV): name=#{feature[:name]}, state=#{feature[:state]}")
219
+ end
190
220
  env[:ui].info(" -- Memory: #{@memory_size / 1024}M")
221
+ unless @nodeset.nil?
222
+ env[:ui].info(" -- Nodeset: #{@nodeset}")
223
+ end
191
224
  @memory_backing.each do |backing|
192
225
  env[:ui].info(" -- Memory Backing: #{backing[:name]}: #{backing[:config].map { |k,v| "#{k}='#{v}'"}.join(' ')}")
193
226
  end
227
+ unless @shares.nil?
228
+ env[:ui].info(" -- Shares: #{@shares}")
229
+ end
194
230
  env[:ui].info(" -- Management MAC: #{@management_network_mac}")
195
231
  env[:ui].info(" -- Loader: #{@loader}")
232
+ env[:ui].info(" -- Nvram: #{@nvram}")
196
233
  if env[:machine].config.vm.box
197
234
  env[:ui].info(" -- Base box: #{env[:machine].box.name}")
198
235
  end
@@ -245,7 +282,7 @@ module VagrantPlugins
245
282
  end
246
283
 
247
284
  @pcis.each do |pci|
248
- env[:ui].info(" -- PCI passthrough: #{pci[:bus]}:#{pci[:slot]}.#{pci[:function]}")
285
+ env[:ui].info(" -- PCI passthrough: #{pci[:domain]}:#{pci[:bus]}:#{pci[:slot]}.#{pci[:function]}")
249
286
  end
250
287
 
251
288
  unless @rng[:model].nil?
@@ -256,6 +293,12 @@ module VagrantPlugins
256
293
  env[:ui].info(" -- Watchdog device: model=#{@watchdog_dev[:model]}, action=#{@watchdog_dev[:action]}")
257
294
  end
258
295
 
296
+ if not @usbctl_dev.empty?
297
+ msg = " -- USB controller: model=#{@usbctl_dev[:model]}"
298
+ msg += ", ports=#{@usbctl_dev[:ports]}" if @usbctl_dev[:ports]
299
+ env[:ui].info(msg)
300
+ end
301
+
259
302
  @usbs.each do |usb|
260
303
  usb_dev = []
261
304
  usb_dev.push("bus=#{usb[:bus]}") if usb[:bus]
@@ -289,18 +332,25 @@ module VagrantPlugins
289
332
  env[:ui].info(" -- smartcard device: mode=#{@smartcard_dev[:mode]}, type=#{@smartcard_dev[:type]}")
290
333
  end
291
334
 
292
- @qargs = config.qemu_args
293
- if not @qargs.empty?
335
+ unless @qemu_args.empty?
294
336
  env[:ui].info(' -- Command line args: ')
295
- @qargs.each do |arg|
337
+ @qemu_args.each do |arg|
296
338
  msg = " -> value=#{arg[:value]}, "
297
339
  env[:ui].info(msg)
298
340
  end
299
341
  end
300
342
 
343
+ unless @qemu_env.empty?
344
+ env[:ui].info(' -- Command line environment variables: ')
345
+ @qemu_env.each do |env_var, env_value|
346
+ msg = " -> #{env_var}=#{env_value}, "
347
+ env[:ui].info(msg)
348
+ end
349
+ end
350
+
301
351
  env[:ui].info(" -- Command line : #{@cmd_line}") unless @cmd_line.empty?
302
352
 
303
- # Create libvirt domain.
353
+ # Create Libvirt domain.
304
354
  # Is there a way to tell fog to create new domain with already
305
355
  # existing volume? Use domain creation from template..
306
356
  begin
@@ -8,6 +8,7 @@ module VagrantPlugins
8
8
  # image as new domain volume.
9
9
  class CreateDomainVolume
10
10
  include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
11
+ include VagrantPlugins::ProviderLibvirt::Util::StorageUtil
11
12
 
12
13
  def initialize(app, _env)
13
14
  @logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain_volume')
@@ -24,15 +25,15 @@ module VagrantPlugins
24
25
  @name = "#{env[:domain_name]}.img"
25
26
 
26
27
  # 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
28
+ domain_volume = env[:machine].provider.driver.connection.volumes.all(
29
+ name: @name
30
+ ).first
31
+ raise Errors::DomainVolumeExists if domain_volume && domain_volume.id
31
32
 
32
33
  # 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
- )
34
+ box_volume = env[:machine].provider.driver.connection.volumes.all(
35
+ name: env[:box_volume_name]
36
+ ).first
36
37
  @backing_file = box_volume.path
37
38
 
38
39
  # Virtual size of image. Take value worked out by HandleBoxImage
@@ -48,9 +49,8 @@ module VagrantPlugins
48
49
  xml.target do
49
50
  xml.format(type: 'qcow2')
50
51
  xml.permissions do
51
- xml.owner 0
52
- xml.group 0
53
- xml.mode '0600'
52
+ xml.owner storage_uid(env)
53
+ xml.group storage_gid(env)
54
54
  xml.label 'virt_image_t'
55
55
  end
56
56
  end
@@ -58,9 +58,8 @@ module VagrantPlugins
58
58
  xml.path(@backing_file)
59
59
  xml.format(type: 'qcow2')
60
60
  xml.permissions do
61
- xml.owner 0
62
- xml.group 0
63
- xml.mode '0600'
61
+ xml.owner storage_uid(env)
62
+ xml.group storage_gid(env)
64
63
  xml.label 'virt_image_t'
65
64
  end
66
65
  end
@@ -70,9 +69,15 @@ module VagrantPlugins
70
69
  Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
71
70
  Nokogiri::XML::Node::SaveOptions::FORMAT
72
71
  )
72
+ if config.snapshot_pool_name != config.storage_pool_name
73
+ pool_name = config.snapshot_pool_name
74
+ else
75
+ pool_name = config.storage_pool_name
76
+ end
77
+ @logger.debug "Using pool #{pool_name} for base box snapshot"
73
78
  domain_volume = env[:machine].provider.driver.connection.volumes.create(
74
79
  xml: xml,
75
- pool_name: config.storage_pool_name
80
+ pool_name: pool_name
76
81
  )
77
82
  rescue Fog::Errors::Error => e
78
83
  raise Errors::FogDomainVolumeCreateError,
@@ -80,6 +80,8 @@ module VagrantPlugins
80
80
  @pci_bus = iface_configuration.fetch(:bus, nil)
81
81
  @pci_slot = iface_configuration.fetch(:slot, nil)
82
82
  template_name = 'interface'
83
+ @type = nil
84
+ @udp_tunnel = nil
83
85
  # Configuration for public interfaces which use the macvtap driver
84
86
  if iface_configuration[:iface_type] == :public_network
85
87
  @device = iface_configuration.fetch(:dev, 'eth0')
@@ -217,10 +219,12 @@ module VagrantPlugins
217
219
  networks_to_configure << network
218
220
  end
219
221
 
220
- env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
221
- env[:machine].guest.capability(
222
- :configure_networks, networks_to_configure
223
- )
222
+ unless networks_to_configure.empty?
223
+ env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
224
+ env[:machine].guest.capability(
225
+ :configure_networks, networks_to_configure
226
+ )
227
+ end
224
228
 
225
229
  end
226
230
  end
@@ -279,7 +283,7 @@ module VagrantPlugins
279
283
  return options[:network_name]
280
284
  end
281
285
 
282
- # Get list of all (active and inactive) libvirt networks.
286
+ # Get list of all (active and inactive) Libvirt networks.
283
287
  available_networks = libvirt_networks(libvirt_client)
284
288
 
285
289
  return 'public' if options[:iface_type] == :public_network
@@ -27,6 +27,11 @@ module VagrantPlugins
27
27
  end
28
28
 
29
29
  def call(env)
30
+ if env[:machine].provider_config.qemu_use_session
31
+ @app.call(env)
32
+ return
33
+ end
34
+
30
35
  # only one vm at a time should try to set up networks
31
36
  # otherwise they'll have inconsitent views of current state
32
37
  # and conduct redundant operations that cause errors
@@ -42,9 +47,9 @@ module VagrantPlugins
42
47
  # should fix other methods so this doesn't have to be instance var
43
48
  @options = options
44
49
 
45
- # Get a list of all (active and inactive) libvirt networks. This
50
+ # Get a list of all (active and inactive) Libvirt networks. This
46
51
  # list is used throughout this class and should be easier to
47
- # process than libvirt API calls.
52
+ # process than Libvirt API calls.
48
53
  @available_networks = libvirt_networks(
49
54
  env[:machine].provider.driver.connection.client
50
55
  )
@@ -14,7 +14,7 @@ module VagrantPlugins
14
14
  env[:ui].info(I18n.t('vagrant_libvirt.destroy_domain'))
15
15
 
16
16
  # Must delete any snapshots before domain can be destroyed
17
- # Fog libvirt currently doesn't support snapshots. Use
17
+ # Fog Libvirt currently doesn't support snapshots. Use
18
18
  # ruby-libvirt client directly. Note this is racy, see
19
19
  # http://www.libvirt.org/html/libvirt-libvirt.html#virDomainSnapshotListNames
20
20
  libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
@@ -13,6 +13,11 @@ module VagrantPlugins
13
13
  end
14
14
 
15
15
  def call(env)
16
+ if env[:machine].provider_config.qemu_use_session
17
+ @app.call(env)
18
+ return
19
+ end
20
+
16
21
  # If there were some networks created for this machine, in machines
17
22
  # data directory, created_networks file holds UUIDs of each network.
18
23
  created_networks_file = env[:machine].data_dir + 'created_networks'
@@ -48,13 +48,13 @@ module VagrantPlugins
48
48
  ))
49
49
 
50
50
  if fp[:protocol] == 'udp'
51
- env[:ui].warn I18n.t('vagrant_libvirt.warnings.forwarding_udp')
51
+ @env[:ui].warn I18n.t('vagrant_libvirt.warnings.forwarding_udp')
52
52
  next
53
53
  end
54
54
 
55
55
  ssh_pid = redirect_port(
56
56
  @env[:machine],
57
- fp[:host_ip] || 'localhost',
57
+ fp[:host_ip] || '*',
58
58
  fp[:host],
59
59
  fp[:guest_ip] || @env[:machine].provider.ssh_info[:host],
60
60
  fp[:guest],
@@ -97,6 +97,8 @@ module VagrantPlugins
97
97
  User=#{ssh_info[:username]}
98
98
  Port=#{ssh_info[:port]}
99
99
  UserKnownHostsFile=/dev/null
100
+ ExitOnForwardFailure=yes
101
+ ControlMaster=no
100
102
  StrictHostKeyChecking=no
101
103
  PasswordAuthentication=no
102
104
  ForwardX11=#{ssh_info[:forward_x11] ? 'yes' : 'no'}
@@ -108,7 +110,7 @@ module VagrantPlugins
108
110
  options += " -o ProxyCommand=\"#{ssh_info[:proxy_command]}\"" if machine.provider_config.connect_via_ssh
109
111
 
110
112
  # TODO: instead of this, try and lock and get the stdin from spawn...
111
- ssh_cmd = 'exec '
113
+ ssh_cmd = ''
112
114
  if host_port <= 1024
113
115
  @@lock.synchronize do
114
116
  # TODO: add i18n
@@ -120,13 +122,13 @@ module VagrantPlugins
120
122
  end
121
123
  end
122
124
 
123
- ssh_cmd << "ssh #{options} #{params}"
125
+ ssh_cmd << "ssh -n #{options} #{params}"
124
126
 
125
127
  @logger.debug "Forwarding port with `#{ssh_cmd}`"
126
128
  log_file = ssh_forward_log_file(host_ip, host_port,
127
129
  guest_ip, guest_port)
128
130
  @logger.info "Logging to #{log_file}"
129
- spawn(ssh_cmd, [:out, :err] => [log_file, 'w'])
131
+ spawn(ssh_cmd, [:out, :err] => [log_file, 'w'], :pgroup => true)
130
132
  end
131
133
 
132
134
  def ssh_forward_log_file(host_ip, host_port, guest_ip, guest_port)
@@ -210,9 +212,9 @@ module VagrantPlugins
210
212
  end
211
213
 
212
214
  def ssh_pid?(pid)
213
- @logger.debug 'Checking if #{pid} is an ssh process '\
214
- 'with `ps -o cmd= #{pid}`'
215
- `ps -o cmd= #{pid}`.strip.chomp =~ /ssh/
215
+ @logger.debug "Checking if #{pid} is an ssh process "\
216
+ "with `ps -o command= #{pid}`"
217
+ `ps -o command= #{pid}`.strip.chomp =~ /ssh/
216
218
  end
217
219
 
218
220
  def remove_ssh_pids