vagrant 0.4.1 → 0.4.2

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.
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  gemspec.homepage = "http://github.com/mitchellh/vagrant"
11
11
  gemspec.authors = ["Mitchell Hashimoto", "John Bender"]
12
12
 
13
- gemspec.add_dependency('virtualbox', '~> 0.7.0')
13
+ gemspec.add_dependency('virtualbox', '~> 0.7.3')
14
14
  gemspec.add_dependency('net-ssh', '>= 2.0.19')
15
15
  gemspec.add_dependency('net-scp', '>= 1.0.2')
16
16
  gemspec.add_dependency('json', '>= 1.2.0')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -27,10 +27,16 @@ Vagrant::Config.run do |config|
27
27
  # other Vagrantfiles, if they wish.
28
28
  config.vm.share_folder("v-root", "/vagrant", ".")
29
29
 
30
- # TODO new config class
31
- config.vm.sync_opts = "-terse -group -owner -batch -silent"
32
- config.vm.sync_script = "/tmp/sync"
33
- config.vm.sync_crontab_entry_file = "/tmp/crontab-entry"
30
+ config.unison.folder_suffix = ".sync"
31
+ config.unison.script = "/tmp/vagrant-unison"
32
+ config.unison.options = "-terse -owner -group -batch"
33
+ config.unison.crontab_entry_file = "/tmp/vagrant-unison-crontab"
34
+ config.unison.log_file = "/tmp/v-unison-log-%s"
35
+
36
+ # TODO fix these
37
+ # config.vm.sync_opts = "-terse -group -owner -batch -silent"
38
+ # config.vm.sync_script = "/tmp/sync"
39
+ # config.vm.sync_crontab_entry_file = "/tmp/crontab-entry"
34
40
 
35
41
  config.package.name = 'vagrant'
36
42
  config.package.extension = '.box'
@@ -100,18 +100,10 @@ module Vagrant
100
100
  def used_ports
101
101
  result = VirtualBox::VM.all.collect do |vm|
102
102
  if vm.running? && vm.uuid != runner.uuid
103
- if VirtualBox.version =~ /^3\.1\./
104
- # VirtualBox 3.1.x uses forwarded ports via extra-data
105
- vm.forwarded_ports.collect do |fp|
103
+ vm.network_adapters.collect do |na|
104
+ na.nat_driver.forwarded_ports.collect do |fp|
106
105
  fp.hostport.to_s
107
106
  end
108
- else
109
- # VirtualBox 3.2.x uses forwarded ports via NAT engines
110
- vm.network_adapters.collect do |na|
111
- na.nat_driver.forwarded_ports.collect do |fp|
112
- fp.hostport.to_s
113
- end
114
- end
115
107
  end
116
108
  end
117
109
  end
@@ -121,34 +113,20 @@ module Vagrant
121
113
 
122
114
  # Deletes existing forwarded ports.
123
115
  def clear_ports
124
- if VirtualBox.version =~ /^3\.1\./
125
- fp = runner.vm.forwarded_ports.dup
126
- fp.each { |p| p.destroy }
127
- else
128
- runner.vm.network_adapters.each do |na|
129
- na.nat_driver.forwarded_ports.dup.each do |fp|
130
- fp.destroy
131
- end
116
+ runner.vm.network_adapters.each do |na|
117
+ na.nat_driver.forwarded_ports.dup.each do |fp|
118
+ fp.destroy
132
119
  end
133
120
  end
134
121
  end
135
122
 
136
123
  # Forwards a port.
137
124
  def forward_port(name, options)
138
- if VirtualBox.version =~ /^3\.1\./
139
- port = VirtualBox::ForwardedPort.new
140
- port.name = name
141
- port.hostport = options[:hostport]
142
- port.guestport = options[:guestport]
143
- port.instance = options[:adapter]
144
- runner.vm.forwarded_ports << port
145
- else
146
- port = VirtualBox::NATForwardedPort.new
147
- port.name = name
148
- port.guestport = options[:guestport]
149
- port.hostport = options[:hostport]
150
- runner.vm.network_adapters[options[:adapter]].nat_driver.forwarded_ports << port
151
- end
125
+ port = VirtualBox::NATForwardedPort.new
126
+ port.name = name
127
+ port.guestport = options[:guestport]
128
+ port.hostport = options[:hostport]
129
+ runner.vm.network_adapters[options[:adapter]].nat_driver.forwarded_ports << port
152
130
  end
153
131
  end
154
132
  end
@@ -2,6 +2,13 @@ module Vagrant
2
2
  module Actions
3
3
  module VM
4
4
  class Network < Base
5
+ def prepare
6
+ # Verify that the given network options are valid
7
+ runner.env.config.vm.network_options.compact.each do |network_options|
8
+ verify_no_bridge_collision(network_options)
9
+ end
10
+ end
11
+
5
12
  def before_destroy
6
13
  # We need to check if the host only network specified by any
7
14
  # of the adapters would not have any more clients if it was
@@ -55,6 +62,24 @@ module Vagrant
55
62
  end
56
63
  end
57
64
 
65
+ # Verifies that there is no collision with a bridged network interface
66
+ # for the given network options.
67
+ def verify_no_bridge_collision(net_options)
68
+ # First try to find a matching network
69
+ interfaces = VirtualBox::Global.global.host.network_interfaces
70
+ interfaces.each do |ni|
71
+ next if ni.interface_type == :host_only
72
+
73
+ result = if net_options[:name]
74
+ true if net_options[:name] == ni.name
75
+ else
76
+ true if matching_network?(ni, net_options)
77
+ end
78
+
79
+ raise ActionException.new(:network_collides) if result
80
+ end
81
+ end
82
+
58
83
  # Returns the name of the proper host only network, or creates
59
84
  # it if it does not exist. Vagrant determines if the host only
60
85
  # network exists by comparing the netmask and the IP.
@@ -62,6 +87,10 @@ module Vagrant
62
87
  # First try to find a matching network
63
88
  interfaces = VirtualBox::Global.global.host.network_interfaces
64
89
  interfaces.each do |ni|
90
+ # Ignore non-host only interfaces which may also match,
91
+ # since they're not valid options.
92
+ next if ni.interface_type != :host_only
93
+
65
94
  if net_options[:name]
66
95
  return ni.name if net_options[:name] == ni.name
67
96
  else
@@ -10,6 +10,8 @@ module Vagrant
10
10
  end
11
11
 
12
12
  def prepare
13
+ raise ActionException.new(:box_file_exists, :output_file => tar_path) if File.exist?(tar_path)
14
+
13
15
  # Verify the existance of all the additional files, if any
14
16
  include_files.each do |file|
15
17
  raise ActionException.new(:package_include_file_doesnt_exist, :filename => file) unless File.exists?(file)
@@ -2,10 +2,34 @@ module Vagrant
2
2
  module Actions
3
3
  module VM
4
4
  class SharedFolders < Base
5
+ # This method returns an actual list of VirtualBox shared
6
+ # folders to create and their proper path.
5
7
  def shared_folders
6
- @runner.env.config.vm.shared_folders.inject([]) do |acc, data|
7
- name, value = data
8
- acc << [name, File.expand_path(value[:hostpath], @runner.env.root_path), value[:guestpath], value[:syncpath]].compact
8
+ runner.env.config.vm.shared_folders.inject({}) do |acc, data|
9
+ key, value = data
10
+
11
+ # This to prevent overwriting the actual shared folders data
12
+ value = value.dup
13
+
14
+ if value[:sync]
15
+ # Syncing this folder. Change the guestpath to reflect
16
+ # what we're actually mounting.
17
+ value[:original] = value.dup
18
+ value[:guestpath] = "#{value[:guestpath]}#{runner.env.config.unison.folder_suffix}"
19
+ end
20
+
21
+ acc[key] = value
22
+ acc
23
+ end
24
+ end
25
+
26
+ # This method returns the list of shared folders which are to
27
+ # be synced via unison.
28
+ def unison_folders
29
+ shared_folders.inject({}) do |acc, data|
30
+ key, value = data
31
+ acc[key] = value if !!value[:sync]
32
+ acc
9
33
  end
10
34
  end
11
35
 
@@ -15,17 +39,30 @@ module Vagrant
15
39
  end
16
40
 
17
41
  def after_boot
42
+ mount_shared_folders
43
+ setup_unison
44
+ end
45
+
46
+ def mount_shared_folders
18
47
  logger.info "Mounting shared folders..."
19
48
 
20
49
  @runner.ssh.execute do |ssh|
21
- @runner.system.prepare_sync(ssh) if @runner.env.config.vm.sync_required
22
-
23
- shared_folders.each do |name, hostpath, guestpath, syncpath|
24
- logger.info "-- #{name}: #{syncpath ? guestpath + " -sync-> " + syncpath : guestpath}"
25
- @runner.system.mount_shared_folder(ssh, name, guestpath)
26
- if syncpath
27
- @runner.system.create_sync(ssh, :syncpath => syncpath, :guestpath => guestpath)
28
- end
50
+ shared_folders.each do |name, data|
51
+ logger.info "-- #{name}: #{data[:guestpath]}"
52
+ @runner.system.mount_shared_folder(ssh, name, data[:guestpath])
53
+ end
54
+ end
55
+ end
56
+
57
+ def setup_unison
58
+ return if unison_folders.empty?
59
+
60
+ runner.ssh.execute do |ssh|
61
+ runner.system.prepare_unison(ssh)
62
+
63
+ logger.info "Creating unison crontab entries..."
64
+ unison_folders.each do |name, data|
65
+ runner.system.create_unison(ssh, data)
29
66
  end
30
67
  end
31
68
  end
@@ -46,10 +83,10 @@ module Vagrant
46
83
  def create_metadata
47
84
  logger.info "Creating shared folders metadata..."
48
85
 
49
- shared_folders.each do |name, hostpath, guestpath|
86
+ shared_folders.each do |name, data|
50
87
  folder = VirtualBox::SharedFolder.new
51
88
  folder.name = name
52
- folder.host_path = hostpath
89
+ folder.host_path = File.expand_path(data[:hostpath], runner.env.root_path)
53
90
  @runner.vm.shared_folders << folder
54
91
  end
55
92
 
@@ -77,6 +77,14 @@ module Vagrant
77
77
  end
78
78
  end
79
79
 
80
+ class UnisonConfig < Base
81
+ attr_accessor :folder_suffix
82
+ attr_accessor :script
83
+ attr_accessor :options
84
+ attr_accessor :crontab_entry_file
85
+ attr_accessor :log_file
86
+ end
87
+
80
88
  class VMConfig < Base
81
89
  include Util::StackedProcRunner
82
90
 
@@ -85,10 +93,6 @@ module Vagrant
85
93
  attr_accessor :box_ovf
86
94
  attr_accessor :base_mac
87
95
  attr_accessor :boot_mode
88
- attr_accessor :sync_opts
89
- attr_accessor :sync_script
90
- attr_accessor :sync_crontab_entry_file
91
- attr_reader :sync_required
92
96
  attr_reader :forwarded_ports
93
97
  attr_reader :shared_folders
94
98
  attr_reader :network_options
@@ -128,19 +132,11 @@ module Vagrant
128
132
  forwarded_ports[name] = options
129
133
  end
130
134
 
131
- def share_folder(name, guestpath, hostpath = nil, opts = {})
132
- guestpath, opts[:sync] = shift(guestpath, opts[:sync])
133
-
134
- # TODO if both are nil the exception information will be unusable
135
- if opts[:sync] == guestpath
136
- raise Exception.new("The sync directory #{opts[:sync]} is identical to the shifted shared folder mount point #{guestpath}")
137
- end
138
-
135
+ def share_folder(name, guestpath, hostpath, opts=nil)
139
136
  @shared_folders[name] = {
140
- :syncpath => opts[:sync],
141
137
  :guestpath => guestpath,
142
138
  :hostpath => hostpath
143
- }
139
+ }.merge(opts || {})
144
140
  end
145
141
 
146
142
  def network(ip, options=nil)
@@ -185,15 +181,6 @@ module Vagrant
185
181
  defined_vms[name.to_sym].options.merge!(options)
186
182
  defined_vms[name.to_sym].push_proc(&block)
187
183
  end
188
-
189
- def shift(orig, sync)
190
- if sync
191
- @sync_required = true
192
- [orig + '-sync', sync == true ? orig : sync]
193
- else
194
- [orig, sync]
195
- end
196
- end
197
184
  end
198
185
 
199
186
  class PackageConfig < Base
@@ -228,6 +215,7 @@ module Vagrant
228
215
  # Setup default configures
229
216
  configures :package, PackageConfig
230
217
  configures :ssh, SSHConfig
218
+ configures :unison, UnisonConfig
231
219
  configures :vm, VMConfig
232
220
  configures :vagrant, VagrantConfig
233
221
 
@@ -40,7 +40,7 @@ module Vagrant
40
40
  version = VirtualBox.version
41
41
  if version.nil?
42
42
  error_and_exit(:virtualbox_not_detected)
43
- elsif version.to_f < 3.1
43
+ elsif version.to_f < 3.2
44
44
  error_and_exit(:virtualbox_invalid_version, :version => version.to_s)
45
45
  elsif version.to_s.downcase.include?("ose")
46
46
  error_and_exit(:virtualbox_invalid_ose, :version => version.to_s)
@@ -24,6 +24,7 @@ module Vagrant
24
24
  end
25
25
 
26
26
  options = {}
27
+ options[:port] = port(opts)
27
28
  [:host, :username, :private_key_path].each do |param|
28
29
  options[param] = opts[param] || env.config.ssh.send(param)
29
30
  end
@@ -35,7 +36,7 @@ module Vagrant
35
36
  # we simply exec.
36
37
  pid = nil
37
38
  pid = fork if Util::Platform.leopard?
38
- Kernel.exec "ssh -p #{port(opts)} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{options[:private_key_path]} #{options[:username]}@#{options[:host]}".strip if pid.nil?
39
+ Kernel.exec "ssh -p #{options[:port]} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{options[:private_key_path]} #{options[:username]}@#{options[:host]}".strip if pid.nil?
39
40
  Process.wait(pid) if pid
40
41
  end
41
42
 
@@ -132,20 +133,13 @@ module Vagrant
132
133
  return pnum if pnum
133
134
 
134
135
  # Check if we have an SSH forwarded port
135
- if VirtualBox.version =~ /^3\.1\./
136
- pnum = env.vm.vm.forwarded_ports.detect do |fp|
136
+ pnum = nil
137
+ env.vm.vm.network_adapters.each do |na|
138
+ pnum = na.nat_driver.forwarded_ports.detect do |fp|
137
139
  fp.name == env.config.ssh.forwarded_port_key
138
140
  end
139
- else
140
- # VirtualBox 3.2 specific
141
- pnum = nil
142
- env.vm.vm.network_adapters.each do |na|
143
- pnum = na.nat_driver.forwarded_ports.detect do |fp|
144
- fp.name == env.config.ssh.forwarded_port_key
145
- end
146
141
 
147
- break if pnum
148
- end
142
+ break if pnum
149
143
  end
150
144
 
151
145
  return pnum.hostport if pnum
@@ -55,6 +55,13 @@ module Vagrant
55
55
  # wants the folder mounted.
56
56
  def mount_shared_folder(ssh, name, guestpath); end
57
57
 
58
+ # Prepares the system for unison folder syncing. This is called
59
+ # once once prior to any `create_unison` calls.
60
+ def prepare_unison(ssh); end
61
+
62
+ # Creates an entry for folder syncing via unison.
63
+ def create_unison(ssh, options); end
64
+
58
65
  # Prepares the system for host only networks. This is called
59
66
  # once prior to any `enable_host_only_network` calls.
60
67
  def prepare_host_only_network; end
@@ -17,7 +17,7 @@ module Vagrant
17
17
  attr_accessor :halt_check_interval
18
18
 
19
19
  def initialize
20
- @halt_timeout = 15
20
+ @halt_timeout = 30
21
21
  @halt_check_interval = 1
22
22
  end
23
23
  end
@@ -49,24 +49,31 @@ module Vagrant
49
49
  def mount_shared_folder(ssh, name, guestpath)
50
50
  ssh.exec!("sudo mkdir -p #{guestpath}")
51
51
  mount_folder(ssh, name, guestpath)
52
- chown(ssh, guestpath)
52
+ ssh.exec!("sudo chown #{config.ssh.username} #{guestpath}")
53
53
  end
54
54
 
55
- def create_sync(ssh, opts)
56
- crontab_entry = render_crontab_entry(opts.merge(:syncopts => config.vm.sync_opts,
57
- :scriptname => config.vm.sync_script))
55
+ def prepare_unison(ssh)
56
+ ssh.exec!("which unison", :error_key => :unison_not_found)
58
57
 
59
- ssh.exec!("sudo mkdir -p #{opts[:syncpath]}")
60
- chown(ssh, opts[:syncpath])
61
- ssh.exec!("sudo echo \"#{crontab_entry}\" >> #{config.vm.sync_crontab_entry_file}")
62
- ssh.exec!("crontab #{config.vm.sync_crontab_entry_file}")
58
+ logger.info "Preparing system for unison sync..."
59
+ vm.ssh.upload!(StringIO.new(TemplateRenderer.render('/unison/script')), config.unison.script)
60
+ ssh.exec!("sudo chmod +x #{config.unison.script}")
61
+ ssh.exec!("sudo rm #{config.unison.crontab_entry_file}", :error_check => false)
63
62
  end
64
63
 
65
- def prepare_sync(ssh)
66
- logger.info "Preparing system for sync..."
67
- vm.ssh.upload!(StringIO.new(render_sync), config.vm.sync_script)
68
- ssh.exec!("sudo chmod +x #{config.vm.sync_script}")
69
- ssh.exec!("sudo rm #{config.vm.sync_crontab_entry_file}", :error_check => false)
64
+ def create_unison(ssh, opts)
65
+ sanitized_string = opts[:original][:guestpath].gsub(/[^a-zA-Z0-9_-]/, '-')
66
+ crontab_entry = TemplateRenderer.render('/unison/crontab_entry',
67
+ :from => opts[:guestpath],
68
+ :to => opts[:original][:guestpath],
69
+ :options => config.unison.options,
70
+ :script => config.unison.script,
71
+ :log_file => (config.unison.log_file % sanitized_string))
72
+
73
+ ssh.exec!("sudo rm -rf ~/.unison")
74
+ ssh.exec!("sudo rm -rf #{opts[:original][:guestpath]}")
75
+ ssh.exec!("sudo echo \"#{crontab_entry}\" >> #{config.unison.crontab_entry_file}")
76
+ ssh.exec!("crontab #{config.unison.crontab_entry_file}")
70
77
  end
71
78
 
72
79
  def prepare_host_only_network
@@ -117,21 +124,9 @@ module Vagrant
117
124
  end
118
125
  end
119
126
 
120
- def chown(ssh, dir)
121
- ssh.exec!("sudo chown #{config.ssh.username} #{dir}")
122
- end
123
-
124
127
  def config
125
128
  vm.env.config
126
129
  end
127
-
128
- def render_sync
129
- TemplateRenderer.render('sync')
130
- end
131
-
132
- def render_crontab_entry(opts)
133
- TemplateRenderer.render('crontab_entry', opts)
134
- end
135
130
  end
136
131
  end
137
132
  end