vagrant 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,12 @@
1
+ ## 1.0.5 (September 18, 2012)
2
+
3
+ - Work around a critical bug in VirtualBox 4.2.0 on Windows that
4
+ causes Vagrant to not work. [GH-1130]
5
+ - Plugin loading works better on Windows by using the proper
6
+ file path separator.
7
+ - NFS works on Fedora 16+. [GH-1140]
8
+ - NFS works with newer versions of Arch hosts that use systemd. [GH-1142]
9
+
1
10
  ## 1.0.4 (September 13, 2012)
2
11
 
3
12
  - VirtualBox 4.2 driver. [GH-1120]
@@ -1,6 +1,7 @@
1
1
  require 'log4r'
2
2
 
3
3
  require 'vagrant/driver/virtualbox_base'
4
+ require 'vagrant/util/platform'
4
5
 
5
6
  module Vagrant
6
7
  module Driver
@@ -11,6 +12,19 @@ module Vagrant
11
12
 
12
13
  @logger = Log4r::Logger.new("vagrant::driver::virtualbox_4_2")
13
14
  @uuid = uuid
15
+
16
+ # "Jank mode." VirtualBox 4.2.0 has a horrendous bug where
17
+ # showvminfo with `--machinereadable` doesn't return proper output.
18
+ # In this case, Vagrant works around it by using equally horrendous
19
+ # regular expressions for the non-machine-readable output of
20
+ # showvminfo. This, ladies and gentlemen, is jank mode.
21
+ @jank_mode = false
22
+ if Util::Platform.windows?
23
+ if execute("--version").start_with?("4.2.0r")
24
+ @logger.info("Windows with v4.2.0. Jank mode engage.")
25
+ @jank_mode = true
26
+ end
27
+ end
14
28
  end
15
29
 
16
30
  def clear_forwarded_ports
@@ -23,6 +37,8 @@ module Vagrant
23
37
  end
24
38
 
25
39
  def clear_shared_folders
40
+ return jank_clear_shared_folders if @jank_mode
41
+
26
42
  info = execute("showvminfo", @uuid, "--machinereadable", :retryable => true)
27
43
  info.split("\n").each do |line|
28
44
  if line =~ /^SharedFolderNameMachineMapping\d+="(.+?)"$/
@@ -71,10 +87,17 @@ module Vagrant
71
87
 
72
88
  execute("list", "vms").split("\n").each do |line|
73
89
  if line =~ /^".+?"\s+\{(.+?)\}$/
74
- info = execute("showvminfo", $1.to_s, "--machinereadable", :retryable => true)
75
- info.split("\n").each do |line|
76
- if line =~ /^hostonlyadapter\d+="(.+?)"$/
77
- networks.delete($1.to_s)
90
+ if @jank_mode
91
+ adapters = jank_read_hostonly_adapters($1.to_s)
92
+ adapters.each do |adapter|
93
+ networks.delete(adapter)
94
+ end
95
+ else
96
+ info = execute("showvminfo", $1.to_s, "--machinereadable", :retryable => true)
97
+ info.split("\n").each do |info_line|
98
+ if info_line =~ /^hostonlyadapter\d+="(.+?)"$/
99
+ networks.delete($1.to_s)
100
+ end
78
101
  end
79
102
  end
80
103
  end
@@ -199,9 +222,10 @@ module Vagrant
199
222
 
200
223
  def read_forwarded_ports(uuid=nil, active_only=false)
201
224
  uuid ||= @uuid
202
-
203
225
  @logger.debug("read_forward_ports: uuid=#{uuid} active_only=#{active_only}")
204
226
 
227
+ return jank_read_forwarded_ports(uuid, active_only) if @jank_mode
228
+
205
229
  results = []
206
230
  current_nic = nil
207
231
  info = execute("showvminfo", uuid, "--machinereadable", :retryable => true)
@@ -306,6 +330,8 @@ module Vagrant
306
330
  end
307
331
 
308
332
  def read_mac_address
333
+ return jank_read_mac_address if @jank_mode
334
+
309
335
  info = execute("showvminfo", @uuid, "--machinereadable", :retryable => true)
310
336
  info.split("\n").each do |line|
311
337
  return $1.to_s if line =~ /^macaddress1="(.+?)"$/
@@ -325,6 +351,8 @@ module Vagrant
325
351
  end
326
352
 
327
353
  def read_network_interfaces
354
+ return jank_read_network_interfaces if @jank_mode
355
+
328
356
  nics = {}
329
357
  info = execute("showvminfo", @uuid, "--machinereadable", :retryable => true)
330
358
  info.split("\n").each do |line|
@@ -353,6 +381,8 @@ module Vagrant
353
381
  end
354
382
 
355
383
  def read_state
384
+ return jank_read_state if @jank_mode
385
+
356
386
  output = execute("showvminfo", @uuid, "--machinereadable", :retryable => true)
357
387
  if output =~ /^name="<inaccessible>"$/
358
388
  return :inaccessible
@@ -454,6 +484,123 @@ module Vagrant
454
484
  def vm_exists?(uuid)
455
485
  raw("showvminfo", uuid).exit_code == 0
456
486
  end
487
+
488
+ protected
489
+
490
+ # JANK MODE METHODS:
491
+ #
492
+ # All the methods below are created to work around a horrendous
493
+ # bug in VirtualBox 4.2.0 on Windows where "showvminfo --machinereadable"
494
+ # doesn't output enough data. So, instead, on Windows we use the plain
495
+ # "showvminfo" and parse the human readable output.
496
+
497
+ def jank_clear_shared_folders
498
+ info = execute("showvminfo", @uuid, :retryable => true)
499
+
500
+ # Get the shared folders part
501
+ info = info.split("\n")
502
+ info = info.drop_while { |line| line !~ /^Shared folders:/i }
503
+ info = info.take_while { |line| line != "" && line !~ /^Name:/i }
504
+
505
+ # Find all the shared folders and delete them all
506
+ info.each do |line|
507
+ if line =~ /^Name: '(.+?)'/
508
+ execute("sharedfolder", "remove", @uuid, "--name", $1.to_s)
509
+ end
510
+ end
511
+ end
512
+
513
+ def jank_read_forwarded_ports(uuid, active_only)
514
+ results = []
515
+
516
+ info = execute("showvminfo", uuid, :retryable => true)
517
+ info.split("\n").each do |line|
518
+ # If we care about active VMs only, then we check the state
519
+ # to verify the VM is running.
520
+ if active_only && line =~ /^State:\s+(.+?) \(.+?\)$/ && $1.to_s != "running"
521
+ return []
522
+ end
523
+
524
+ # Parse out the forwarded port information
525
+ if line =~ /^NIC (\d) Rule\(\d\):\s+name = (.+?), protocol = .+?, host ip = .*?, host port = (.+?), guest ip = .*?, guest port = (.+?)$/
526
+ result = [$1.to_i, $2.to_s, $3.to_i, $4.to_i]
527
+ @logger.debug(" - #{result.inspect}")
528
+ results << result
529
+ end
530
+ end
531
+
532
+ results
533
+ end
534
+
535
+ def jank_read_hostonly_adapters(uuid)
536
+ adapters = []
537
+
538
+ nics = jank_read_network_interfaces(uuid)
539
+ nics.each do |adapter, data|
540
+ if data[:type] == :hostonly
541
+ adapters << data[:hostonly]
542
+ end
543
+ end
544
+
545
+ adapters
546
+ end
547
+
548
+ def jank_read_mac_address
549
+ info = execute("showvminfo", @uuid, :retryable => true)
550
+ info.split("\n").each do |line|
551
+ return $1.to_s if line =~ /^NIC 1:\s+MAC: (.+?),/
552
+ end
553
+
554
+ nil
555
+ end
556
+
557
+ def jank_read_network_interfaces(uuid=nil)
558
+ uuid ||= @uuid
559
+ nics = {}
560
+ info = execute("showvminfo", uuid, :retryable => true)
561
+ info.split("\n").each do |line|
562
+ if line =~ /^NIC (\d):\s+MAC: .+?, Attachment: (.+?), Cable/
563
+ adapter = $1.to_i
564
+ long_type = $2.to_s
565
+
566
+ type = nil
567
+ data = nil
568
+ if long_type == "NAT"
569
+ type = :nat
570
+ elsif long_type =~ /^Host-only Interface '(.+?)'$/i
571
+ type = :hostonly
572
+ data = $1.to_s
573
+ elsif long_type =~ /^Bridged Interface '(.+?)'$/i
574
+ type = :bridge
575
+ data = $1.to_s
576
+ end
577
+
578
+ nics[adapter] ||= {}
579
+ nics[adapter][:type] = type
580
+ nics[adapter][:hostonly] = data if type == :hostonly
581
+ nics[adapter][:bridge] = data if type == :bridge
582
+ end
583
+ end
584
+
585
+ nics
586
+ end
587
+
588
+ def jank_read_state
589
+ output = execute("showvminfo", @uuid, :retryable => true)
590
+ if output =~ /^Name:\s+<inaccessible>$/
591
+ return :inaccessible
592
+ elsif output =~ /^State:\s+(.+?) \(.+?\)$/
593
+ # Silly edge cases for a jank mode. This probably doesn't
594
+ # cover every case, but if we can get Vagrant MOSTLY working
595
+ # with this buggy version of VirtualBox on Windows, I'll be
596
+ # quite happy.
597
+ state = $1.to_s.downcase.gsub(" ", "")
598
+ state = "poweroff" if state == "poweredoff"
599
+ return state.to_sym
600
+ end
601
+
602
+ nil
603
+ end
457
604
  end
458
605
  end
459
606
  end
@@ -507,7 +507,7 @@ module Vagrant
507
507
  def load_plugins
508
508
  # Add our private gem path to the gem path and reset the paths
509
509
  # that Rubygems knows about.
510
- ENV["GEM_PATH"] = "#{@gems_path}:#{ENV["GEM_PATH"]}"
510
+ ENV["GEM_PATH"] = "#{@gems_path}#{::File::PATH_SEPARATOR}#{ENV["GEM_PATH"]}"
511
511
  ::Gem.clear_paths
512
512
 
513
513
  # Load the plugins
@@ -2,7 +2,7 @@ module Vagrant
2
2
  module Hosts
3
3
  class Arch < Linux
4
4
  def self.match?
5
- File.exist?("/etc/rc.conf") && File.exist?("/etc/pacman.conf")
5
+ File.exist?("/etc/os-release") && File.read("/etc/os-release") =~ /arch linux/i
6
6
  end
7
7
 
8
8
  # Normal, mid-range precedence.
@@ -19,17 +19,36 @@ module Vagrant
19
19
  @ui.info I18n.t("vagrant.hosts.arch.nfs_export.prepare")
20
20
  sleep 0.5
21
21
 
22
+ nfs_cleanup(id)
23
+
22
24
  output.split("\n").each do |line|
23
25
  # This should only ask for administrative permission once, even
24
26
  # though its executed in multiple subshells.
25
27
  system(%Q[sudo su root -c "echo '#{line}' >> /etc/exports"])
26
28
  end
27
29
 
28
- # We run restart here instead of "update" just in case nfsd
29
- # is not starting
30
- system("sudo /etc/rc.d/rpcbind restart")
31
- system("sudo /etc/rc.d/nfs-common restart")
32
- system("sudo /etc/rc.d/nfs-server restart")
30
+ if systemd?
31
+ # Call start to be nice. This will be a no-op if things are
32
+ # already running. Then use exportfs to pick up the changes we
33
+ # just made.
34
+ system("sudo systemctl start nfsd.service rpc-idmapd.service rpc-mountd.service rpcbind.service")
35
+ system("sudo exportfs -r")
36
+ else
37
+ # The restarting of services when we might not need to can be
38
+ # considered evil, but this will be obviated by systemd soon
39
+ # enough anyway.
40
+ system("sudo /etc/rc.d/rpcbind restart")
41
+ system("sudo /etc/rc.d/nfs-common restart")
42
+ system("sudo /etc/rc.d/nfs-server restart")
43
+ end
44
+ end
45
+
46
+ protected
47
+
48
+ # This tests to see if systemd is used on the system. This is used
49
+ # in newer versions of Arch, and requires a change in behavior.
50
+ def systemd?
51
+ Kernel.system("which systemctl &>/dev/null")
33
52
  end
34
53
  end
35
54
  end
@@ -24,6 +24,23 @@ module Vagrant
24
24
  super
25
25
 
26
26
  @nfs_server_binary = "/etc/init.d/nfs"
27
+
28
+ # On Fedora 16+, systemd replaced init.d, so we have to use the
29
+ # proper NFS binary. This checks to see if we need to do that.
30
+ release_file = Pathname.new("/etc/redhat-release")
31
+ begin
32
+ release_file.open("r") do |f|
33
+ version_number = /Fedora release ([0-9]+)/.match(f.gets)[1].to_i
34
+ if version_number >= 16
35
+ # "service nfs-server" will redirect properly to systemctl
36
+ # when "service nfs-server restart" is called.
37
+ @nfs_server_binary = "/usr/sbin/service nfs-server"
38
+ end
39
+ end
40
+ rescue Errno::ENOENT
41
+ # File doesn't exist, not a big deal, assume we're on a
42
+ # lower version.
43
+ end
27
44
  end
28
45
  end
29
46
  end
@@ -2,5 +2,5 @@ module Vagrant
2
2
  # This will always be up to date with the current version of Vagrant,
3
3
  # since it is used to generate the gemspec and is also the source of
4
4
  # the version for `vagrant -v`
5
- VERSION = "1.0.4"
5
+ VERSION = "1.0.5"
6
6
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 4
10
- version: 1.0.4
9
+ - 5
10
+ version: 1.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mitchell Hashimoto
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-09-14 00:00:00 Z
19
+ date: 2012-09-19 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: archive-tar-minitar