vagrant 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,24 @@
1
+ ## 0.9.4 (January 28, 2012)
2
+
3
+ - Important internal changes to middlewares that make plugin developer's
4
+ lives much easier. [GH-684]
5
+ - Match VM names that have parens, brackets, etc.
6
+ - Detect when the VirtualBox kernel module is not loaded and error. [GH-677]
7
+ - Set `:auto_config` to false on any networking option to not automatically
8
+ configure it on the guest. [GH-663]
9
+ - NFS shared folder guest paths can now contain shell expansion characters
10
+ such as `~`.
11
+ - NFS shared folders with a `:create` flag will have their host folders
12
+ properly created if they don't exist. [GH-667]
13
+ - Fix the precedence for Arch, Ubuntu, and FreeBSD host classes so
14
+ they are properly detected. [GH-683]
15
+ - Fix issue where VM import sometimes made strange VirtualBox folder
16
+ layouts. [GH-669]
17
+ - Call proper `id` command on Solaris. [GH-679]
18
+ - More accurate VBoxManage error detection.
19
+ - Shared folders can now be marked as transient using the `:transient`
20
+ flag. [GH-688]
21
+
1
22
  ## 0.9.3 (January 24, 2012)
2
23
 
3
24
  - Proper error handling for not enough arguments to `box` commands.
@@ -74,6 +74,12 @@ module Vagrant
74
74
  autoload :Util, 'vagrant/util'
75
75
  autoload :VM, 'vagrant/vm'
76
76
 
77
+ # Returns a `Vagrant::Registry` object that contains all the built-in
78
+ # middleware stacks.
79
+ def self.actions
80
+ @actions ||= Vagrant::Action::Builtin.new
81
+ end
82
+
77
83
  # The source root is the path to the root directory of
78
84
  # the Vagrant gem.
79
85
  def self.source_root
@@ -1,8 +1,8 @@
1
1
  require 'vagrant/action/builder'
2
- require 'vagrant/action/builtin'
3
2
 
4
3
  module Vagrant
5
4
  module Action
5
+ autoload :Builtin, 'vagrant/action/builtin'
6
6
  autoload :Environment, 'vagrant/action/environment'
7
7
  autoload :Runner, 'vagrant/action/runner'
8
8
  autoload :Warden, 'vagrant/action/warden'
@@ -35,6 +35,7 @@ module Vagrant
35
35
  autoload :ClearNetworkInterfaces, 'vagrant/action/vm/clear_network_interfaces'
36
36
  autoload :ClearSharedFolders, 'vagrant/action/vm/clear_shared_folders'
37
37
  autoload :Customize, 'vagrant/action/vm/customize'
38
+ autoload :DefaultName, 'vagrant/action/vm/default_name'
38
39
  autoload :Destroy, 'vagrant/action/vm/destroy'
39
40
  autoload :DestroyUnusedNetworkInterfaces, 'vagrant/action/vm/destroy_unused_network_interfaces'
40
41
  autoload :DiscardState, 'vagrant/action/vm/discard_state'
@@ -1,144 +1,158 @@
1
1
  module Vagrant
2
2
  module Action
3
- # Registers the builtin actions with a specific registry.
4
- #
5
- # These are the pre-built action sequences that are shipped with
6
- # Vagrant itself.
7
- def self.builtin!(registry)
8
- # provision - Provisions a running VM
9
- registry.register(:provision) do
10
- Builder.new do
11
- use General::Validate
12
- use VM::CheckAccessible
13
- use VM::Provision
14
- end
3
+ # A registry object containing the built-in middleware stacks.
4
+ class Builtin < Registry
5
+ def initialize
6
+ # Properly initialize the registry object
7
+ super
8
+
9
+ # Register all the built-in stacks
10
+ register_builtin!
15
11
  end
16
12
 
17
- # start - Starts a VM, assuming it already exists on the
18
- # environment.
19
- registry.register(:start) do
20
- Builder.new do
21
- use General::Validate
22
- use VM::CheckAccessible
23
- use VM::CleanMachineFolder
24
- use VM::ClearForwardedPorts
25
- use VM::CheckPortCollisions, :port_collision_handler => :correct
26
- use VM::ForwardPorts
27
- use VM::Provision
28
- use VM::PruneNFSExports
29
- use VM::NFS
30
- use VM::ClearSharedFolders
31
- use VM::ShareFolders
32
- use VM::HostName
33
- use VM::ClearNetworkInterfaces
34
- use VM::Network
35
- use VM::Customize
36
- use VM::Boot
13
+ protected
14
+
15
+ def register_builtin!
16
+ # We do this so that the blocks below have a variable to access the
17
+ # outer registry.
18
+ registry = self
19
+
20
+ # provision - Provisions a running VM
21
+ register(:provision) do
22
+ Builder.new do
23
+ use General::Validate
24
+ use VM::CheckAccessible
25
+ use VM::Provision
26
+ end
37
27
  end
38
- end
39
28
 
40
- # halt - Halts the VM, attempting gracefully but then forcing
41
- # a restart if fails.
42
- registry.register(:halt) do
43
- Builder.new do
44
- use General::Validate
45
- use VM::CheckAccessible
46
- use VM::DiscardState
47
- use VM::Halt
29
+ # start - Starts a VM, assuming it already exists on the
30
+ # environment.
31
+ register(:start) do
32
+ Builder.new do
33
+ use General::Validate
34
+ use VM::CheckAccessible
35
+ use VM::CleanMachineFolder
36
+ use VM::ClearForwardedPorts
37
+ use VM::CheckPortCollisions, :port_collision_handler => :correct
38
+ use VM::ForwardPorts
39
+ use VM::Provision
40
+ use VM::PruneNFSExports
41
+ use VM::NFS
42
+ use VM::ClearSharedFolders
43
+ use VM::ShareFolders
44
+ use VM::HostName
45
+ use VM::ClearNetworkInterfaces
46
+ use VM::Network
47
+ use VM::Customize
48
+ use VM::Boot
49
+ end
48
50
  end
49
- end
50
51
 
51
- # suspend - Suspends the VM
52
- registry.register(:suspend) do
53
- Builder.new do
54
- use General::Validate
55
- use VM::CheckAccessible
56
- use VM::Suspend
52
+ # halt - Halts the VM, attempting gracefully but then forcing
53
+ # a restart if fails.
54
+ register(:halt) do
55
+ Builder.new do
56
+ use General::Validate
57
+ use VM::CheckAccessible
58
+ use VM::DiscardState
59
+ use VM::Halt
60
+ end
57
61
  end
58
- end
59
62
 
60
- # resume - Resume a VM
61
- registry.register(:resume) do
62
- Builder.new do
63
- use General::Validate
64
- use VM::CheckAccessible
65
- use VM::CheckPortCollisions
66
- use VM::Resume
63
+ # suspend - Suspends the VM
64
+ register(:suspend) do
65
+ Builder.new do
66
+ use General::Validate
67
+ use VM::CheckAccessible
68
+ use VM::Suspend
69
+ end
67
70
  end
68
- end
69
71
 
70
- # reload - Halts then restarts the VM
71
- registry.register(:reload) do
72
- Builder.new do
73
- use General::Validate
74
- use VM::CheckAccessible
75
- use registry.get(:halt)
76
- use registry.get(:start)
72
+ # resume - Resume a VM
73
+ register(:resume) do
74
+ Builder.new do
75
+ use General::Validate
76
+ use VM::CheckAccessible
77
+ use VM::CheckPortCollisions
78
+ use VM::Resume
79
+ end
77
80
  end
78
- end
79
81
 
80
- # up - Imports, prepares, then starts a fresh VM.
81
- registry.register(:up) do
82
- Builder.new do
83
- use General::Validate
84
- use VM::CheckAccessible
85
- use VM::CheckBox
86
- use VM::Import
87
- use VM::CheckGuestAdditions
88
- use VM::MatchMACAddress
89
- use registry.get(:start)
82
+ # reload - Halts then restarts the VM
83
+ register(:reload) do
84
+ Builder.new do
85
+ use General::Validate
86
+ use VM::CheckAccessible
87
+ use registry.get(:halt)
88
+ use registry.get(:start)
89
+ end
90
90
  end
91
- end
92
91
 
93
- # destroy - Halts, cleans up, and destroys an existing VM
94
- registry.register(:destroy) do
95
- Builder.new do
96
- use General::Validate
97
- use VM::CheckAccessible
98
- use registry.get(:halt), :force => true
99
- use VM::ProvisionerCleanup
100
- use VM::PruneNFSExports
101
- use VM::Destroy
102
- use VM::CleanMachineFolder
103
- use VM::DestroyUnusedNetworkInterfaces
92
+ # up - Imports, prepares, then starts a fresh VM.
93
+ register(:up) do
94
+ Builder.new do
95
+ use General::Validate
96
+ use VM::CheckAccessible
97
+ use VM::CheckBox
98
+ use VM::Import
99
+ use VM::CheckGuestAdditions
100
+ use VM::DefaultName
101
+ use VM::MatchMACAddress
102
+ use registry.get(:start)
103
+ end
104
104
  end
105
- end
106
105
 
107
- # package - Export and package the VM
108
- registry.register(:package) do
109
- Builder.new do
110
- use General::Validate
111
- use VM::SetupPackageFiles
112
- use VM::CheckAccessible
113
- use registry.get(:halt)
114
- use VM::ClearForwardedPorts
115
- use VM::ClearSharedFolders
116
- use VM::Export
117
- use VM::PackageVagrantfile
118
- use VM::Package
106
+ # destroy - Halts, cleans up, and destroys an existing VM
107
+ register(:destroy) do
108
+ Builder.new do
109
+ use General::Validate
110
+ use VM::CheckAccessible
111
+ use registry.get(:halt), :force => true
112
+ use VM::ProvisionerCleanup
113
+ use VM::PruneNFSExports
114
+ use VM::Destroy
115
+ use VM::CleanMachineFolder
116
+ use VM::DestroyUnusedNetworkInterfaces
117
+ end
119
118
  end
120
- end
121
119
 
122
- # box_add - Download and add a box.
123
- registry.register(:box_add) do
124
- Builder.new do
125
- use Box::Download
126
- use Box::Unpackage
127
- use Box::Verify
120
+ # package - Export and package the VM
121
+ register(:package) do
122
+ Builder.new do
123
+ use General::Validate
124
+ use VM::SetupPackageFiles
125
+ use VM::CheckAccessible
126
+ use registry.get(:halt)
127
+ use VM::ClearForwardedPorts
128
+ use VM::ClearSharedFolders
129
+ use VM::Export
130
+ use VM::PackageVagrantfile
131
+ use VM::Package
132
+ end
128
133
  end
129
- end
130
134
 
131
- # box_remove - Removes/deletes a box.
132
- registry.register(:box_remove) do
133
- Builder.new do
134
- use Box::Destroy
135
+ # box_add - Download and add a box.
136
+ register(:box_add) do
137
+ Builder.new do
138
+ use Box::Download
139
+ use Box::Unpackage
140
+ use Box::Verify
141
+ end
142
+ end
143
+
144
+ # box_remove - Removes/deletes a box.
145
+ register(:box_remove) do
146
+ Builder.new do
147
+ use Box::Destroy
148
+ end
135
149
  end
136
- end
137
150
 
138
- # box_repackage - Repackages a box.
139
- registry.register(:box_repackage) do
140
- Builder.new do
141
- use Box::Package
151
+ # box_repackage - Repackages a box.
152
+ register(:box_repackage) do
153
+ Builder.new do
154
+ use Box::Package
155
+ end
142
156
  end
143
157
  end
144
158
  end
@@ -0,0 +1,22 @@
1
+ require 'log4r'
2
+
3
+ module Vagrant
4
+ module Action
5
+ module VM
6
+ class DefaultName
7
+ def initialize(app, env)
8
+ @logger = Log4r::Logger.new("vagrant::action::vm::defaultname")
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ @logger.info("Setting the default name of the VM")
14
+ name = env[:root_path].basename.to_s + "_#{Time.now.to_i}"
15
+ env[:vm].driver.set_name(name)
16
+
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -10,9 +10,8 @@ module Vagrant
10
10
  env[:ui].info I18n.t("vagrant.actions.vm.import.importing", :name => env[:vm].box.name)
11
11
 
12
12
  # Import the virtual machine
13
- name = File.basename(env[:vm].env.cwd) + "_#{Time.now.to_i}"
14
13
  ovf_file = env[:vm].box.directory.join("box.ovf").to_s
15
- env[:vm].uuid = env[:vm].driver.import(ovf_file, name) do |progress|
14
+ env[:vm].uuid = env[:vm].driver.import(ovf_file) do |progress|
16
15
  env[:ui].clear_line
17
16
  env[:ui].report_progress(progress, 100, false)
18
17
  end
@@ -37,8 +37,12 @@ module Vagrant
37
37
  adapters << adapter
38
38
 
39
39
  # Get the network configuration
40
- network = send("#{type}_network_config", config)
41
- networks << network
40
+ if config[:auto_config]
41
+ network = send("#{type}_network_config", config)
42
+ networks << network
43
+ else
44
+ @logger.info("Auto config disabled, not configuring: #{type}")
45
+ end
42
46
  end
43
47
 
44
48
  if !adapters.empty?
@@ -167,7 +171,8 @@ module Vagrant
167
171
  :netmask => "255.255.255.0",
168
172
  :adapter => nil,
169
173
  :mac => nil,
170
- :name => nil
174
+ :name => nil,
175
+ :auto_config => true
171
176
  }.merge(options)
172
177
 
173
178
  # Verify that this hostonly network wouldn't conflict with any
@@ -307,7 +312,8 @@ module Vagrant
307
312
 
308
313
  return {
309
314
  :adapter => nil,
310
- :mac => nil
315
+ :mac => nil,
316
+ :auto_config => true
311
317
  }.merge(options)
312
318
  end
313
319
 
@@ -1,3 +1,8 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+
4
+ require 'log4r'
5
+
1
6
  module Vagrant
2
7
  module Action
3
8
  module VM
@@ -15,6 +20,7 @@ module Vagrant
15
20
  #
16
21
  class NFS
17
22
  def initialize(app,env)
23
+ @logger = Log4r::Logger.new("vagrant::action::vm::nfs")
18
24
  @app = app
19
25
  @env = env
20
26
 
@@ -46,18 +52,35 @@ module Vagrant
46
52
  # task.
47
53
  def extract_folders
48
54
  # Load the NFS enabled shared folders
49
- @folders = @env[:vm].config.vm.shared_folders.inject({}) do |acc, data|
50
- key, opts = data
51
-
55
+ @folders = {}
56
+ @env[:vm].config.vm.shared_folders.each do |key, opts|
52
57
  if opts[:nfs]
53
58
  # Duplicate the options, set the hostpath, and set disabled on the original
54
59
  # options so the ShareFolders middleware doesn't try to mount it.
55
- acc[key] = opts.dup
56
- acc[key][:hostpath] = File.expand_path(opts[:hostpath], @env[:root_path])
60
+ folder = opts.dup
61
+ hostpath = Pathname.new(opts[:hostpath]).expand_path(@env[:root_path])
62
+
63
+ if !hostpath.directory? && opts[:create]
64
+ # Host path doesn't exist, so let's create it.
65
+ @logger.debug("Host path doesn't exist, creating: #{hostpath}")
66
+
67
+ begin
68
+ FileUtils.mkpath(hostpath)
69
+ rescue Errno::EACCES
70
+ raise Errors::SharedFolderCreateFailed, :path => hostpath.to_s
71
+ end
72
+ end
73
+
74
+ # Set the hostpath now that it exists.
75
+ folder[:hostpath] = hostpath.to_s
76
+
77
+ # Assign the folder to our instance variable for later use
78
+ @folders[key] = folder
79
+
80
+ # Disable the folder so that regular shared folders don't try to
81
+ # mount it.
57
82
  opts[:disabled] = true
58
83
  end
59
-
60
- acc
61
84
  end
62
85
  end
63
86
 
@@ -63,7 +63,8 @@ module Vagrant
63
63
  shared_folders.each do |name, data|
64
64
  folders << {
65
65
  :name => name,
66
- :hostpath => File.expand_path(data[:hostpath], @env[:root_path])
66
+ :hostpath => File.expand_path(data[:hostpath], @env[:root_path]),
67
+ :transient => data[:transient]
67
68
  }
68
69
  end
69
70
 
@@ -79,6 +79,7 @@ Please change your configurations to match this new syntax.
79
79
  :owner => nil,
80
80
  :group => nil,
81
81
  :nfs => false,
82
+ :transient => false,
82
83
  :extra => nil
83
84
  }.merge(opts || {})
84
85
  end
@@ -94,6 +94,7 @@ module Vagrant
94
94
  :read_used_ports,
95
95
  :read_vms,
96
96
  :set_mac_address,
97
+ :set_name,
97
98
  :share_folders,
98
99
  :ssh_port,
99
100
  :start,
@@ -117,7 +118,12 @@ module Vagrant
117
118
 
118
119
  # Note: We split this into multiple lines because apparently "".split("_")
119
120
  # is [], so we have to check for an empty array in between.
120
- parts = execute("--version").split("_")
121
+ output = execute("--version")
122
+ if output =~ /vboxdrv kernel module is not loaded/
123
+ raise Errors::VirtualBoxKernelModuleNotLoaded
124
+ end
125
+
126
+ parts = output.split("_")
121
127
  return nil if parts.empty?
122
128
  parts[0].split("r")[0]
123
129
  end
@@ -9,7 +9,7 @@ module Vagrant
9
9
  def initialize(uuid)
10
10
  super()
11
11
 
12
- @logger = Log4r::Logger.new("vagrant::driver::virtualbox_4_1")
12
+ @logger = Log4r::Logger.new("vagrant::driver::virtualbox_4_0")
13
13
  @uuid = uuid
14
14
  end
15
15
 
@@ -147,11 +147,15 @@ module Vagrant
147
147
  execute("controlvm", @uuid, "poweroff")
148
148
  end
149
149
 
150
- def import(ovf, name)
150
+ def import(ovf)
151
+ output = ""
151
152
  total = ""
152
153
  last = 0
153
- execute("import", ovf, "--vsys", "0", "--vmname", name) do |type, data|
154
- if type == :stderr
154
+ execute("import", ovf) do |type, data|
155
+ if type == :stdout
156
+ # Keep track of the stdout so that we can get the VM name
157
+ output << data
158
+ elsif type == :stderr
155
159
  # Append the data so we can see the full view
156
160
  total << data
157
161
 
@@ -171,8 +175,16 @@ module Vagrant
171
175
  end
172
176
  end
173
177
 
178
+ # Find the name of the VM name
179
+ if output !~ /Suggested VM name "(.+?)"/
180
+ @logger.error("Couldn't find VM name in the output.")
181
+ return nil
182
+ end
183
+
184
+ name = $1.to_s
185
+
174
186
  output = execute("list", "vms")
175
- if output =~ /^"#{name}" \{(.+?)\}$/
187
+ if output =~ /^"#{Regexp.escape(name)}" \{(.+?)\}$/
176
188
  return $1.to_s
177
189
  end
178
190
 
@@ -274,7 +286,7 @@ module Vagrant
274
286
  elsif line =~ /^NetworkMask:\s+(.+?)$/
275
287
  info[:netmask] = $1.to_s
276
288
  elsif line =~ /^Status:\s+(.+?)$/
277
- info[:status] = $1.to_s
289
+ info[:status] = $1.to_s
278
290
  end
279
291
  end
280
292
 
@@ -374,10 +386,18 @@ module Vagrant
374
386
  execute("modifyvm", @uuid, "--macaddress1", mac)
375
387
  end
376
388
 
389
+ def set_name(name)
390
+ execute("modifyvm", @uuid, "--name", name)
391
+ end
392
+
377
393
  def share_folders(folders)
378
394
  folders.each do |folder|
379
- execute("sharedfolder", "add", @uuid, "--name",
380
- folder[:name], "--hostpath", folder[:hostpath])
395
+ args = ["--name",
396
+ folder[:name],
397
+ "--hostpath",
398
+ folder[:hostpath]]
399
+ args << "--transient" if folder.has_key?(:transient) && folder[:transient]
400
+ execute("sharedfolder", "add", @uuid, *args)
381
401
  end
382
402
  end
383
403
 
@@ -147,11 +147,15 @@ module Vagrant
147
147
  execute("controlvm", @uuid, "poweroff")
148
148
  end
149
149
 
150
- def import(ovf, name)
150
+ def import(ovf)
151
+ output = ""
151
152
  total = ""
152
153
  last = 0
153
- execute("import", ovf, "--vsys", "0", "--vmname", name) do |type, data|
154
- if type == :stderr
154
+ execute("import", ovf) do |type, data|
155
+ if type == :stdout
156
+ # Keep track of the stdout so that we can get the VM name
157
+ output << data
158
+ elsif type == :stderr
155
159
  # Append the data so we can see the full view
156
160
  total << data
157
161
 
@@ -171,8 +175,16 @@ module Vagrant
171
175
  end
172
176
  end
173
177
 
178
+ # Find the name of the VM name
179
+ if output !~ /Suggested VM name "(.+?)"/
180
+ @logger.error("Couldn't find VM name in the output.")
181
+ return nil
182
+ end
183
+
184
+ name = $1.to_s
185
+
174
186
  output = execute("list", "vms")
175
- if output =~ /^"#{name}" \{(.+?)\}$/
187
+ if output =~ /^"#{Regexp.escape(name)}" \{(.+?)\}$/
176
188
  return $1.to_s
177
189
  end
178
190
 
@@ -374,10 +386,18 @@ module Vagrant
374
386
  execute("modifyvm", @uuid, "--macaddress1", mac)
375
387
  end
376
388
 
389
+ def set_name(name)
390
+ execute("modifyvm", @uuid, "--name", name)
391
+ end
392
+
377
393
  def share_folders(folders)
378
394
  folders.each do |folder|
379
- execute("sharedfolder", "add", @uuid, "--name",
380
- folder[:name], "--hostpath", folder[:hostpath])
395
+ args = ["--name",
396
+ folder[:name],
397
+ "--hostpath",
398
+ folder[:hostpath]]
399
+ args << "--transient" if folder.has_key?(:transient) && folder[:transient]
400
+ execute("sharedfolder", "add", @uuid, *args)
381
401
  end
382
402
  end
383
403
 
@@ -133,9 +133,8 @@ module Vagrant
133
133
  # Imports the VM from an OVF file.
134
134
  #
135
135
  # @param [String] ovf Path to the OVF file.
136
- # @param [String] name Name of the VM.
137
136
  # @return [String] UUID of the imported VM.
138
- def import(ovf, name)
137
+ def import(ovf)
139
138
  end
140
139
 
141
140
  # Returns a list of forwarded ports for a VM.
@@ -261,6 +260,14 @@ module Vagrant
261
260
  else
262
261
  raise Errors::VBoxManageError, :command => command.inspect
263
262
  end
263
+ else
264
+ # Sometimes, VBoxManage fails but doesn't actual return a non-zero
265
+ # exit code. For this we inspect the output and determine if an error
266
+ # occurred.
267
+ if r.stderr =~ /VBoxManage: error:/
268
+ @logger.info("VBoxManage error text found, assuming error.")
269
+ raise Errors::VBoxManageError, :command => command.inspect
270
+ end
264
271
  end
265
272
 
266
273
  # Return the output, making sure to replace any Windows-style
@@ -197,13 +197,10 @@ module Vagrant
197
197
  #
198
198
  # @return [Registry]
199
199
  def action_registry
200
- return @action_registry if defined?(@action_registry)
201
-
202
- # The action registry hasn't been loaded yet, so load it
203
- # and setup the built-in actions with it.
204
- @action_registry = Registry.new
205
- Vagrant::Action.builtin!(@action_registry)
206
- @action_registry
200
+ # For now we return the global built-in actions registry. In the future
201
+ # we may want to create an isolated registry that inherits from this
202
+ # global one, but for now there isn't a use case that calls for it.
203
+ Vagrant.actions
207
204
  end
208
205
 
209
206
  # Loads on initial access and reads data from the global data store.
@@ -343,6 +343,11 @@ module Vagrant
343
343
  error_key(:virtualbox_not_detected)
344
344
  end
345
345
 
346
+ class VirtualBoxKernelModuleNotLoaded < VagrantError
347
+ status_code(70)
348
+ error_key(:virtualbox_kernel_module_not_loaded)
349
+ end
350
+
346
351
  class VMBaseMacNotSpecified < VagrantError
347
352
  status_code(47)
348
353
  error_key(:no_base_mac, "vagrant.actions.vm.match_mac")
@@ -43,25 +43,7 @@ module Vagrant
43
43
  end
44
44
 
45
45
  def mount_shared_folder(name, guestpath, options)
46
- # Determine the real guest path. Since we use a `sudo` shell everywhere
47
- # else, things like '~' don't expand properly in shared folders. We have
48
- # to `echo` here to get that path.
49
- real_guestpath = nil
50
- @vm.channel.execute("printf #{guestpath}") do |type, data|
51
- if type == :stdout
52
- real_guestpath ||= ""
53
- real_guestpath += data
54
- end
55
- end
56
-
57
- if !real_guestpath
58
- # Really strange error case if this happens. Let's throw an error,
59
- # tell the user to check the echo output.
60
- raise LinuxError, :_key => :guestpath_expand_fail
61
- end
62
-
63
- # Chomp off the newline if it exists
64
- real_guestpath = real_guestpath.chomp
46
+ real_guestpath = expanded_guest_path(guestpath)
65
47
  @logger.debug("Shell expanded guest path: #{real_guestpath}")
66
48
 
67
49
  @vm.channel.sudo("mkdir -p #{real_guestpath}")
@@ -73,16 +55,44 @@ module Vagrant
73
55
  # TODO: Maybe check for nfs support on the guest, since its often
74
56
  # not installed by default
75
57
  folders.each do |name, opts|
76
- @vm.channel.sudo("mkdir -p #{opts[:guestpath]}")
77
- @vm.channel.sudo("mount #{ip}:'#{opts[:hostpath]}' #{opts[:guestpath]}",
58
+ # Expand the guestpath, so we can handle things like "~/vagrant"
59
+ real_guestpath = expanded_guest_path(opts[:guestpath])
60
+
61
+ # Do the actual creating and mounting
62
+ @vm.channel.sudo("mkdir -p #{real_guestpath}")
63
+ @vm.channel.sudo("mount #{ip}:'#{opts[:hostpath]}' #{real_guestpath}",
78
64
  :error_class => LinuxError,
79
65
  :error_key => :mount_nfs_fail)
80
66
  end
81
67
  end
82
68
 
83
- #-------------------------------------------------------------------
84
- # "Private" methods which assist above methods
85
- #-------------------------------------------------------------------
69
+ protected
70
+
71
+ # Determine the real guest path. Since we use a `sudo` shell everywhere
72
+ # else, things like '~' don't expand properly in shared folders. We have
73
+ # to `echo` here to get that path.
74
+ #
75
+ # @param [String] guestpath The unexpanded guest path.
76
+ # @return [String] The expanded guestpath
77
+ def expanded_guest_path(guestpath)
78
+ real_guestpath = nil
79
+ @vm.channel.execute("printf #{guestpath}") do |type, data|
80
+ if type == :stdout
81
+ real_guestpath ||= ""
82
+ real_guestpath += data
83
+ end
84
+ end
85
+
86
+ if !real_guestpath
87
+ # Really strange error case if this happens. Let's throw an error,
88
+ # tell the user to check the echo output.
89
+ raise LinuxError, :_key => :guestpath_expand_fail
90
+ end
91
+
92
+ # Chomp the string so that any trailing newlines are killed
93
+ return real_guestpath.chomp
94
+ end
95
+
86
96
  def mount_folder(name, guestpath, options)
87
97
  # Determine the permission string to attach to the mount command
88
98
  mount_options = "-o uid=`id -u #{options[:owner]}`,gid=`id -g #{options[:group]}`"
@@ -101,13 +101,17 @@ module Vagrant
101
101
  # Create the shared folder
102
102
  vm.channel.execute("#{vm.config.solaris.suexec_cmd} mkdir -p #{guestpath}")
103
103
 
104
+ # We have to use this `id` command instead of `/usr/bin/id` since this
105
+ # one accepts the "-u" and "-g" flags.
106
+ id_cmd = "/usr/xpg4/bin/id"
107
+
104
108
  # Mount the folder with the proper owner/group
105
- mount_options = "-o uid=`id -u #{owner}`,gid=`id -g #{group}`"
109
+ mount_options = "-o uid=`#{id_cmd} -u #{owner}`,gid=`#{id_cmd} -g #{group}`"
106
110
  mount_options += ",#{options[:extra]}" if options[:extra]
107
111
  vm.channel.execute("#{vm.config.solaris.suexec_cmd} /sbin/mount -F vboxfs #{mount_options} #{name} #{guestpath}")
108
112
 
109
113
  # chown the folder to the proper owner/group
110
- vm.channel.execute("#{vm.config.solaris.suexec_cmd} chown `id -u #{owner}`:`id -g #{group}` #{guestpath}")
114
+ vm.channel.execute("#{vm.config.solaris.suexec_cmd} chown `#{id_cmd} -u #{owner}`:`#{id_cmd} -g #{group}` #{guestpath}")
111
115
  end
112
116
  end
113
117
  end
@@ -1,3 +1,5 @@
1
+ require 'log4r'
2
+
1
3
  module Vagrant
2
4
  module Hosts
3
5
  autoload :Base, 'vagrant/hosts/base'
@@ -11,13 +13,19 @@ module Vagrant
11
13
  # This method detects the correct host based on the `match?` methods
12
14
  # implemented in the registered hosts.
13
15
  def self.detect(registry)
16
+ logger = Log4r::Logger.new("vagrant::hosts")
17
+
14
18
  # Sort the hosts by their precedence
15
19
  host_klasses = registry.to_hash.values
16
20
  host_klasses = host_klasses.sort_by { |a| a.precedence }.reverse
21
+ logger.debug("Host path search classes: #{host_klasses.inspect}")
17
22
 
18
23
  # Test for matches and return the host class that matches
19
24
  host_klasses.each do |klass|
20
- return klass if klass.match?
25
+ if klass.match?
26
+ logger.info("Host class: #{klass}")
27
+ return klass
28
+ end
21
29
  end
22
30
 
23
31
  # No matches found...
@@ -5,6 +5,11 @@ module Vagrant
5
5
  File.exist?("/etc/rc.conf") && File.exist?("/etc/pacman.conf")
6
6
  end
7
7
 
8
+ # Normal, mid-range precedence.
9
+ def self.precedence
10
+ 5
11
+ end
12
+
8
13
  def nfs_export(id, ip, folders)
9
14
  output = TemplateRenderer.render('nfs/exports_linux',
10
15
  :uuid => id,
@@ -15,6 +15,11 @@ module Vagrant
15
15
  false
16
16
  end
17
17
 
18
+ # Normal, mid-range precedence.
19
+ def self.precedence
20
+ 5
21
+ end
22
+
18
23
  def initialize(*args)
19
24
  super
20
25
 
@@ -11,6 +11,11 @@ module Vagrant
11
11
  Util::Platform.freebsd?
12
12
  end
13
13
 
14
+ # Normal, mid-range precedence.
15
+ def self.precedence
16
+ 5
17
+ end
18
+
14
19
  def initialize(*args)
15
20
  super
16
21
 
@@ -130,7 +130,7 @@ module Vagrant
130
130
  def verify_binary(binary)
131
131
  env[:vm].channel.sudo("which #{binary}",
132
132
  :error_class => PuppetError,
133
- :error_key => :puppet_not_detected,
133
+ :error_key => :not_detected,
134
134
  :binary => binary)
135
135
  end
136
136
 
@@ -29,7 +29,7 @@ module Vagrant
29
29
  def verify_binary(binary)
30
30
  env[:vm].channel.sudo("which #{binary}",
31
31
  :error_class => PuppetServerError,
32
- :error_key => :puppetd_not_detected,
32
+ :error_key => :not_detected,
33
33
  :binary => binary)
34
34
  end
35
35
 
@@ -46,12 +46,7 @@ module Vagrant
46
46
 
47
47
  env[:ui].info I18n.t("vagrant.provisioners.puppet_server.running_puppetd")
48
48
  env[:vm].channel.sudo(command) do |type, data|
49
- # Output the data with the proper color based on the stream.
50
- color = type == :stdout ? :green : :red
51
-
52
- # Note: Be sure to chomp the data to avoid the newlines that the
53
- # Chef outputs.
54
- env[:ui].info(data.chomp, :color => color, :prefix => false)
49
+ env[:ui].info(data.chomp, :prefix => false)
55
50
  end
56
51
  end
57
52
  end
@@ -6,6 +6,7 @@ module Vagrant
6
6
  class Registry
7
7
  def initialize
8
8
  @actions = {}
9
+ @results_cache = {}
9
10
  end
10
11
 
11
12
  # Register a callable by key.
@@ -26,8 +27,10 @@ module Vagrant
26
27
  # action stack.
27
28
  def get(key)
28
29
  return nil if !@actions.has_key?(key)
29
- @actions[key].call
30
+ return @results_cache[key] if @results_cache.has_key?(key)
31
+ @results_cache[key] = @actions[key].call
30
32
  end
33
+ alias :[] :get
31
34
 
32
35
  # Iterate over the keyspace.
33
36
  def each(&block)
@@ -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 = "0.9.3"
5
+ VERSION = "0.9.4"
6
6
  end
@@ -16,16 +16,6 @@ en:
16
16
  errors:
17
17
  base_vm_not_found: The base VM with the name '%{name}' was not found.
18
18
  box_not_found: Box '%{name}' could not be found.
19
- chef_not_detected: |-
20
- The chef (either `chef-solo` or `chef-client`) binary was not found on
21
- the VM and is required for chef provisioning. Please verify that chef
22
- is installed and that the binary is available on the PATH.
23
- puppet_not_detected: |-
24
- The `puppet` binary was not found on the VM and is required for Puppet provisioning.
25
- Please verify that Puppet is installed and that the binary is available on the PATH.
26
- puppetd_not_detected: |-
27
- The `puppetd` binary was not found on the VM is required for Puppet Server provisioning.
28
- Please verify that Puppet is installed and that the binary is available on the PATH.
29
19
  cli_invalid_options: |-
30
20
  An invalid option was specified. The help for this command
31
21
  is available below.
@@ -166,6 +156,10 @@ en:
166
156
  listed below to use Vagrant:
167
157
 
168
158
  %{supported_versions}
159
+ virtualbox_kernel_module_not_loaded: |-
160
+ VirtualBox is complaining that the kernel module is not loaded. Please
161
+ run `VBoxManage --version` to see the error message which should contain
162
+ instructions on how to fix this error.
169
163
  virtualbox_not_detected: |-
170
164
  Vagrant could not detect VirtualBox! Make sure VirtualBox is properly installed.
171
165
  Vagrant uses the `VBoxManage` binary that ships with VirtualBox, and requires
@@ -563,6 +557,10 @@ en:
563
557
 
564
558
  provisioners:
565
559
  chef:
560
+ chef_not_detected: |-
561
+ The chef binary (either `chef-solo` or `chef-client`) was not found on
562
+ the VM and is required for chef provisioning. Please verify that chef
563
+ is installed and that the binary is available on the PATH.
566
564
  json: "Generating chef JSON and uploading..."
567
565
  client_key_folder: "Creating folder to hold client key..."
568
566
  upload_validation_key: "Uploading chef client validation key..."
@@ -20,7 +20,7 @@ describe Vagrant::Registry do
20
20
  end.to_not raise_error
21
21
  end
22
22
 
23
- it "should call and return the result of a block when asking for the ite" do
23
+ it "should call and return the result of a block when asking for the item" do
24
24
  object = Object.new
25
25
  instance.register("foo") do
26
26
  object
@@ -29,6 +29,24 @@ describe Vagrant::Registry do
29
29
  instance.get("foo").should eql(object)
30
30
  end
31
31
 
32
+ it "should be able to get the item with []" do
33
+ object = Object.new
34
+ instance.register("foo") { object }
35
+
36
+ instance["foo"].should eql(object)
37
+ end
38
+
39
+ it "should cache the result of the item so they can be modified" do
40
+ # Make the proc generate a NEW array each time
41
+ instance.register("foo") { [] }
42
+
43
+ # Test that modifying the result modifies the actual cached
44
+ # value. This verifies we're caching.
45
+ instance.get("foo").should == []
46
+ instance.get("foo") << "value"
47
+ instance.get("foo").should == ["value"]
48
+ end
49
+
32
50
  it "should be enumerable" do
33
51
  instance.register("foo", "foovalue")
34
52
  instance.register("bar", "barvalue")
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: 61
4
+ hash: 51
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 3
10
- version: 0.9.3
9
+ - 4
10
+ version: 0.9.4
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-01-24 00:00:00 Z
19
+ date: 2012-01-29 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -304,6 +304,7 @@ files:
304
304
  - lib/vagrant/action/vm/clear_network_interfaces.rb
305
305
  - lib/vagrant/action/vm/clear_shared_folders.rb
306
306
  - lib/vagrant/action/vm/customize.rb
307
+ - lib/vagrant/action/vm/default_name.rb
307
308
  - lib/vagrant/action/vm/destroy.rb
308
309
  - lib/vagrant/action/vm/destroy_unused_network_interfaces.rb
309
310
  - lib/vagrant/action/vm/discard_state.rb