diff --git a/lib/vagrant/vagrantfile.rb b/lib/vagrant/vagrantfile.rb index 1bf64750e..27d9dcb52 100644 --- a/lib/vagrant/vagrantfile.rb +++ b/lib/vagrant/vagrantfile.rb @@ -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 diff --git a/test/unit/vagrant/vagrantfile_test.rb b/test/unit/vagrant/vagrantfile_test.rb index 39e783db7..129bb5874 100644 --- a/test/unit/vagrant/vagrantfile_test.rb +++ b/test/unit/vagrant/vagrantfile_test.rb @@ -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