core: upgrade to v1.5 box dir format if it can

This commit is contained in:
Mitchell Hashimoto 2014-01-22 11:10:59 -08:00
parent 5253da79cd
commit b52d33e0af
4 changed files with 166 additions and 44 deletions

View File

@ -304,6 +304,38 @@ module Vagrant
return true
end
# This upgrades a v1.1 - v1.4 box directory structure up to a v1.5
# directory structure. This will raise exceptions if it fails in any
# way.
def upgrade_v1_1_v1_5
with_collection_lock do
temp_dir = Pathname.new(Dir.mktmpdir(TEMP_PREFIX, @temp_root))
@directory.children(true).each do |boxdir|
# Ignore all non-directories because they can't be boxes
next if !boxdir.directory?
box_name = boxdir.basename.to_s
# If it is a v1 box, then we need to upgrade it first
upgrade(box_name) if v1_box?(boxdir)
# Create the directory for this box
new_box_dir = temp_dir.join(box_name, "0")
new_box_dir.mkpath
# Go through each provider and move it
boxdir.children(true).each do |providerdir|
FileUtils.cp_r(providerdir, new_box_dir.join(providerdir.basename))
end
end
# Move the folder into place
@directory.rmtree
FileUtils.mv(temp_dir.to_s, @directory.to_s)
end
end
protected
# This checks if the given directory represents a V1 box on the

View File

@ -18,7 +18,7 @@ module Vagrant
# compatible with in the home directory.
#
# @return [String]
CURRENT_SETUP_VERSION = "1.1"
CURRENT_SETUP_VERSION = "1.5"
DEFAULT_LOCAL_DATA = ".vagrant"
@ -636,9 +636,28 @@ module Vagrant
raise Errors::HomeDirectoryNotAccessible, home_path: @home_path.to_s
end
# Create the version file to mark the version of the home directory
# we're using.
# Create the version file that we use to track the structure of
# the home directory. If we have an old version, we need to explicitly
# upgrade it. Otherwise, we just mark that its the current version.
version_file = @home_path.join("setup_version")
if version_file.file?
version = version_file.read
case version
when CURRENT_SETUP_VERSION
# We're already good, at the latest version.
when "1.1"
# We need to update our directory structure
upgrade_home_path_v1_1
# Delete the version file so we put our latest version in
version_file.delete
else
raise Errors::HomeDirectoryUnknownVersion,
path: @home_path.to_s,
version: version
end
end
if !version_file.file?
@logger.debug(
"Creating home directory version file: #{CURRENT_SETUP_VERSION}")
@ -647,17 +666,6 @@ module Vagrant
end
end
# Determine if we need to update the directory structure
version = version_file.read
case version
when CURRENT_SETUP_VERSION
# We're already good, at the latest version.
else
raise Errors::HomeDirectoryUnknownVersion,
path: @home_path.to_s,
version: version
end
# Create the rgloader/loader file so we can use encoded files.
loader_file = @home_path.join("rgloader", "loader.rb")
if !loader_file.file?
@ -741,6 +749,14 @@ module Vagrant
nil
end
# This upgrades a home directory that was in the v1.1 format to the
# v1.5 format. It will raise exceptions if anything fails.
def upgrade_home_path_v1_1
collection = BoxCollection.new(
@home_path.join("boxes"), temp_dir_root: tmp_path)
collection.upgrade_v1_1_v1_5
end
# This upgrades a Vagrant 1.0.x "dotfile" to the new V2 format.
#
# This is a destructive process. Once the upgrade is complete, the

View File

@ -10,6 +10,8 @@ describe Vagrant::BoxCollection do
let(:environment) { isolated_environment }
let(:instance) { described_class.new(environment.boxes_dir) }
subject { instance }
it "should tell us the directory it is using" do
instance.directory.should == environment.boxes_dir
end
@ -238,4 +240,48 @@ describe Vagrant::BoxCollection do
instance.upgrade("foo").should be
end
end
describe "#upgrade_v1_1_v1_5" do
let(:boxes_dir) { environment.boxes_dir }
before do
# Create all the various box directories
@foo_path = boxes_dir.join("foo", "virtualbox")
@vbox_path = boxes_dir.join("precise64", "virtualbox")
@vmware_path = boxes_dir.join("precise64", "vmware")
@v1_path = boxes_dir.join("v1box")
[@foo_path, @vbox_path, @vmware_path].each do |path|
path.mkpath
path.join("name").open("w") do |f|
f.write(path.to_s)
end
end
@v1_path.mkpath
@v1_path.join("box.ovf").open("w") { |f| f.write("yep!") }
@v1_path.join("name").open("w") { |f| f.write("v1box") }
end
it "upgrades the boxes" do
subject.upgrade_v1_1_v1_5
# The old paths should not exist anymore
expect(@foo_path).to_not exist
expect(@vbox_path).to_not exist
expect(@vmware_path).to_not exist
expect(@v1_path.join("box.ovf")).to_not exist
# New paths should exist
foo_path = boxes_dir.join("foo", "0", "virtualbox")
vbox_path = boxes_dir.join("precise64", "0", "virtualbox")
vmware_path = boxes_dir.join("precise64", "0", "vmware")
v1_path = boxes_dir.join("v1box", "0", "virtualbox")
expect(foo_path).to exist
expect(vbox_path).to exist
expect(vmware_path).to exist
expect(v1_path).to exist
end
end
end

View File

@ -49,36 +49,7 @@ describe Vagrant::Environment do
}.to raise_error(Vagrant::Errors::HomeDirectoryNotAccessible)
end
context "default home path" do
it "is set to '~/.vagrant.d' by default" do
expected = Vagrant::Util::Platform.fs_real_path("~/.vagrant.d")
described_class.new.home_path.should == expected
end
it "is set to '~/.vagrant.d' if on Windows but no USERPROFILE" do
Vagrant::Util::Platform.stub(:windows? => true)
expected = Vagrant::Util::Platform.fs_real_path("~/.vagrant.d")
with_temp_env("USERPROFILE" => nil) do
described_class.new.home_path.should == expected
end
end
it "is set to '%USERPROFILE%/.vagrant.d' if on Windows and USERPROFILE is set" do
Vagrant::Util::Platform.stub(:windows? => true)
Dir.mktmpdir do |dir|
expected = Vagrant::Util::Platform.fs_real_path("#{dir}/.vagrant.d")
with_temp_env("USERPROFILE" => dir) do
described_class.new.home_path.should == expected
end
end
end
end
context "setup version file" do
context "with setup version file" do
it "creates a setup version flie" do
path = subject.home_path.join("setup_version")
expect(path).to be_file
@ -109,6 +80,63 @@ describe Vagrant::Environment do
end
end
end
context "upgrading a v1.1 directory structure" do
let(:env) { isolated_environment }
before do
env.homedir.join("setup_version").open("w") do |f|
f.write("1.1")
end
end
it "replaces the setup version with the new version" do
expect(subject.home_path.join("setup_version").read).
to eq(Vagrant::Environment::CURRENT_SETUP_VERSION)
end
it "moves the boxes into the new directory structure" do
# Kind of hacky but avoids two instantiations of BoxCollection
Vagrant::Environment.any_instance.stub(boxes: double("boxes"))
collection = double("collection")
Vagrant::BoxCollection.should_receive(:new).with(
env.homedir.join("boxes"), anything).and_return(collection)
collection.should_receive(:upgrade_v1_1_v1_5).once
subject
end
=begin
# Create all the old box directories
boxdir = env.homedir.join("boxes")
boxdir.mkpath
foo_path = boxdir.join("foo", "virtualbox")
vbox_path = boxdir.join("precise64", "virtualbox")
vmware_path = boxdir.join("precise64", "vmware")
v1_path = boxdir.join("v1box")
[foo_path, vbox_path, vmware_path].each do |path|
path.mkpath
path.join("name").open("w") do |f|
f.write(path.to_s)
end
end
v1_path.mkpath
v1_path.join("name").open("w") { |f| f.write("v1box") }
# Upgrade!
subject
expect(boxdir).to be_directory
expect(boxdir.children(false).map(&:to_s).sort).to eq(
["foo", "precise64", "v1box"])
expect(foo_path).to_not exist
expect(vbox_path).to_not exist
expect(vmware_path).to_not exist
expect(v1_path).to_not exist
=end
end
end
describe "#host" do