Avoid cross-device moves when adding boxes [GH-1350]

This commit is contained in:
Mitchell Hashimoto 2013-02-02 16:37:46 -08:00
parent 2dc14af825
commit ec995b5ddf
1 changed files with 15 additions and 12 deletions

View File

@ -87,7 +87,7 @@ module Vagrant
# Create a temporary directory since we're not sure at this point if # Create a temporary directory since we're not sure at this point if
# the box we're unpackaging already exists (if no provider was given) # the box we're unpackaging already exists (if no provider was given)
Dir.mktmpdir(TEMP_PREFIX, directory.to_s) do |temp_dir| Dir.mktmpdir(TEMP_PREFIX) do |temp_dir|
temp_dir = Pathname.new(temp_dir) temp_dir = Pathname.new(temp_dir)
# Extract the box into a temporary directory. # Extract the box into a temporary directory.
@ -125,13 +125,20 @@ module Vagrant
check_box_exists.call(provider) check_box_exists.call(provider)
end end
# Create the directory that'll store our box # Create the directory for this box, not including the provider
final_dir = @directory.join(name, provider.to_s) box_dir = @directory.join(name)
@logger.debug("Final box directory: #{final_dir}") box_dir.mkpath
final_dir.mkpath @logger.debug("Box directory: #{box_dir}")
# Move to the final destination # This is the final directory we'll move it to
File.rename(temp_dir, final_dir.to_s) final_dir = box_dir.join(provider.to_s)
if final_dir.exist?
@logger.debug("Removing existing provider directory...")
final_dir.rmtree
end
# Move to final destination
FileUtils.mv(temp_dir.to_s, final_dir.to_s)
# Recreate the directory. This avoids a bug in Ruby where `mktmpdir` # Recreate the directory. This avoids a bug in Ruby where `mktmpdir`
# cleanup doesn't check if the directory is already gone. Ruby bug # cleanup doesn't check if the directory is already gone. Ruby bug
@ -160,10 +167,6 @@ module Vagrant
box_name = child.basename.to_s box_name = child.basename.to_s
# Ignore anything that matches the temporary prefix (crazy
# race condition might be possible)
next if box_name =~ /^#{TEMP_PREFIX}/
# If this is a V1 box, we still return that name, but specify # If this is a V1 box, we still return that name, but specify
# that the box is a V1 box. # that the box is a V1 box.
if v1_box?(child) if v1_box?(child)
@ -247,7 +250,7 @@ module Vagrant
temp_dir = v1_upgrade(box_dir) temp_dir = v1_upgrade(box_dir)
# Rename the temporary directory to the provider. # Rename the temporary directory to the provider.
temp_dir.rename(box_dir.join("virtualbox")) FileUtils.mv(temp_dir.to_s, box_dir.join("virtualbox").to_s)
@logger.info("Box '#{name}' upgraded from V1 to V2.") @logger.info("Box '#{name}' upgraded from V1 to V2.")
end end