From 648be1369f390606828e5cab2bcce188bf133905 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Fri, 2 Nov 2018 13:59:53 -0700 Subject: [PATCH] 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. --- lib/vagrant/vagrantfile.rb | 15 ++++++-- test/unit/vagrant/vagrantfile_test.rb | 52 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) 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