Fallback to Vagrantfile configuration when local metadata lookup fails

The project local metadata file may contain invalid information to properly
lookup the configured box. This may occur if the file has been moved,
modified, or the backing box has been removed. In those cases, fall back
to the configuration defined in the Vagrantfile to load the box.
This commit is contained in:
Chris Roberts 2018-11-02 13:59:53 -07:00
parent 872c3c957d
commit 648be1369f
2 changed files with 65 additions and 2 deletions

View File

@ -170,8 +170,8 @@ module Vagrant
# Track the original box so we know if we changed
box = nil
original_box = config.vm.box
original_version = config.vm.box_version
initial_box = original_box = config.vm.box
initial_version = original_version = config.vm.box_version
# Check if this machine has a local box metadata file
# describing the existing guest. If so, load it and
@ -232,6 +232,17 @@ module Vagrant
# Load the box and provider overrides
load_box_proc.call
# NOTE: In cases where the box_meta file contains stale information
# and the reference box no longer exists, fall back to initial
# configuration and attempt to load that
if box.nil?
@logger.warn("Failed to locate #{config.vm.box} with version #{config.vm.box_version}")
@logger.warn("Performing lookup with inital values #{initial_box} with version #{initial_version}")
config.vm.box = original_box = initial_box
config.vm.box_version = original_box = initial_version
load_box_proc.call
end
# Ensure box attributes are set to original values in
# case they were modified by the local box metadata
config.vm.box = original_box

View File

@ -367,6 +367,58 @@ describe Vagrant::Vagrantfile do
expect { subject.machine_config(:default, :foo, boxes) }.
to raise_error(Vagrant::Errors::ProviderNotUsable)
end
context "local box metadata file" do
let(:data_path) { double(:data_path) }
let(:meta_file) { double(:meta_file) }
let(:box_version) { "2.0" }
before do
register_provider("foo")
iso_env.box3("base", "1.0", :foo)
allow(data_path).to receive(:join).with("box_meta").
and_return(meta_file)
allow(meta_file).to receive(:file?).and_return(false)
configure do |config|
config.vm.box = "base"
config.vm.box_version = box_version
end
end
it "checks for local box metadata file" do
expect(meta_file).to receive(:file?).and_return(false)
subject.machine_config(:default, :foo, boxes, data_path)
end
context "file exists" do
let(:meta_file_content) { '{"name":"base","version":"1.0"}' }
before do
allow(meta_file).to receive(:file?).and_return(true)
allow(meta_file).to receive(:read).and_return(meta_file_content)
end
it "reads the local box metadata file" do
expect(meta_file).to receive(:read).and_return(meta_file_content)
subject.machine_config(:default, :foo, boxes, data_path)
end
it "properly loads the box defined in metadata" do
result = subject.machine_config(:default, :foo, boxes, data_path)
expect(result[:box]).not_to be_nil
end
context "with invalid box version" do
let(:box_version) { "1.0" }
let(:meta_file_content) { '{"name":"base","version":"2.0"}' }
it "loads box base on Vagrantfile information" do
result = subject.machine_config(:default, :foo, boxes, data_path)
expect(result[:box]).not_to be_nil
end
end
end
end
end
describe "#machine_names" do