diff --git a/lib/vagrant/action/builtin/box_check_outdated.rb b/lib/vagrant/action/builtin/box_check_outdated.rb index 0399a1686..eecad9911 100644 --- a/lib/vagrant/action/builtin/box_check_outdated.rb +++ b/lib/vagrant/action/builtin/box_check_outdated.rb @@ -31,6 +31,36 @@ module Vagrant raise Errors::BoxOutdatedNoBox, name: machine.config.vm.box end + if env[:box_outdated_refresh] + @logger.info( + "Checking if box is outdated by refreshing metadata") + check_outdated_refresh(env) + else + @logger.info("Checking if box is outdated locally") + check_outdated_local(env) + end + + @app.call(env) + end + + def check_outdated_local(env) + machine = env[:machine] + box = env[:box_collection].find( + machine.box.name, machine.box.provider, + "> #{machine.box.version}") + if box + env[:ui].warn(I18n.t( + "vagrant.box_outdated_local", + name: box.name, + old: machine.box.version, + new: box.version)) + env[:box_outdated] = true + end + end + + def check_outdated_refresh(env) + machine = env[:machine] + if !machine.box.metadata_url # This box doesn't have a metadata URL, so we can't # possibly check the version information. @@ -49,7 +79,7 @@ module Vagrant end env[:box_outdated] = false - return @app.call(env) + return end env[:ui].warn(I18n.t( @@ -58,8 +88,6 @@ module Vagrant current: machine.box.version, latest: newer.version)) env[:box_outdated] = true - - @app.call(env) end end end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 1a0c7d7df..f41d6e559 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -30,6 +30,11 @@ en: Loading metadata for box '%{name}' box_outdated: |- * '%{name}' is outdated! Current: %{current}. Latest: %{latest} + box_outdated_local: |- + A newer version of the box '%{name}' is available and already + installed, but your Vagrant machine is running against + version '%{old}'. To update to version '%{new}', + destroy and recreate your machine. box_outdated_single: |- A newer version of the box '%{name}' is available! You currently have version '%{current}'. The latest is version '%{latest}'. Run diff --git a/test/unit/vagrant/action/builtin/box_check_outdated_test.rb b/test/unit/vagrant/action/builtin/box_check_outdated_test.rb index e0ff697a7..3c08777c6 100644 --- a/test/unit/vagrant/action/builtin/box_check_outdated_test.rb +++ b/test/unit/vagrant/action/builtin/box_check_outdated_test.rb @@ -5,6 +5,7 @@ describe Vagrant::Action::Builtin::BoxCheckOutdated do let(:app) { lambda { |env| } } let(:env) { { + box_collection: iso_vagrant_env.boxes, machine: machine, ui: Vagrant::UI::Silent.new, } } @@ -37,37 +38,70 @@ describe Vagrant::Action::Builtin::BoxCheckOutdated do end end - context "box with no metadata_url" do - let(:box) do - box_dir = iso_env.box3("foo", "1.0", :virtualbox) - Vagrant::Box.new("foo", :virtualbox, "1.0", box_dir) - end - + context "without refreshing" do before do + env[:box_outdated_refresh] = false + machine.stub(box: box) end - it "raises an exception" do - app.should_receive(:call).never + it "isn't outdated if there are no newer boxes" do + iso_env.box3("foo", "0.5", :virtualbox) - expect { subject.call(env) }. - to raise_error(Vagrant::Errors::BoxOutdatedNoMetadata) + app.should_receive(:call).with(env) + + subject.call(env) + + expect(env[:box_outdated]).to be_false + end + + it "is outdated if there are newer boxes" do + iso_env.box3("foo", "1.5", :virtualbox) + + app.should_receive(:call).with(env) + + subject.call(env) + + expect(env[:box_outdated]).to be_true end end - context "with a metadata URL" do - let(:metadata_url) do - Tempfile.new("vagrant").tap do |f| - f.close + context "with refreshing" do + before do + env[:box_outdated_refresh] = true + end + + context "no metadata URL" do + let(:box) do + box_dir = iso_env.box3("foo", "1.0", :virtualbox) + Vagrant::Box.new("foo", :virtualbox, "1.0", box_dir) + end + + before do + machine.stub(box: box) + end + + it "raises an exception" do + app.should_receive(:call).never + + expect { subject.call(env) }. + to raise_error(Vagrant::Errors::BoxOutdatedNoMetadata) end end - let(:box_dir) { iso_env.box3("foo", "1.0", :virtualbox) } + context "with metadata URL" do + let(:metadata_url) do + Tempfile.new("vagrant").tap do |f| + f.close + end + end - context "isn't outdated" do - before do - File.open(metadata_url.path, "w") do |f| - f.write(<<-RAW) + let(:box_dir) { iso_env.box3("foo", "1.0", :virtualbox) } + + context "isn't outdated" do + before do + File.open(metadata_url.path, "w") do |f| + f.write(<<-RAW) { "name": "foo/bar", "versions": [ @@ -82,47 +116,47 @@ describe Vagrant::Action::Builtin::BoxCheckOutdated do } ] } - RAW + RAW + end + + box = Vagrant::Box.new( + "foo", :virtualbox, "1.0", box_dir, + metadata_url: metadata_url.path) + machine.stub(box: box) end - box = Vagrant::Box.new( - "foo", :virtualbox, "1.0", box_dir, - metadata_url: metadata_url.path) - machine.stub(box: box) + it "marks it isn't outdated" do + app.should_receive(:call).with(env) + + subject.call(env) + + expect(env[:box_outdated]).to be_false + end + + it "talks to the UI" do + env[:box_outdated_success_ui] = true + + app.should_receive(:call).with(env) + env[:ui].should_receive(:success) + + subject.call(env) + + expect(env[:box_outdated]).to be_false + end + + it "doesn't talk to UI if it is told" do + app.should_receive(:call).with(env) + env[:ui].should_receive(:success).never + + subject.call(env) + + expect(env[:box_outdated]).to be_false + end end - it "marks it isn't outdated" do - app.should_receive(:call).with(env) - - subject.call(env) - - expect(env[:box_outdated]).to be_false - end - - it "talks to the UI" do - env[:box_outdated_success_ui] = true - - app.should_receive(:call).with(env) - env[:ui].should_receive(:success) - - subject.call(env) - - expect(env[:box_outdated]).to be_false - end - - it "doesn't talk to UI if it is told" do - app.should_receive(:call).with(env) - env[:ui].should_receive(:success).never - - subject.call(env) - - expect(env[:box_outdated]).to be_false - end - end - - it "is outdated if it is" do - File.open(metadata_url.path, "w") do |f| - f.write(<<-RAW) + it "is outdated if it is" do + File.open(metadata_url.path, "w") do |f| + f.write(<<-RAW) { "name": "foo/bar", "versions": [ @@ -140,21 +174,21 @@ describe Vagrant::Action::Builtin::BoxCheckOutdated do } ] } - RAW + RAW + end + + box = Vagrant::Box.new( + "foo", :virtualbox, "1.0", box_dir, metadata_url: metadata_url.path) + machine.stub(box: box) + + subject.call(env) + + expect(env[:box_outdated]).to be_true end - box = Vagrant::Box.new( - "foo", :virtualbox, "1.0", box_dir, metadata_url: metadata_url.path) - machine.stub(box: box) - - subject.call(env) - - expect(env[:box_outdated]).to be_true - end - - it "isn't outdated if the newer box is for another provider" do - File.open(metadata_url.path, "w") do |f| - f.write(<<-RAW) + it "isn't outdated if the newer box is for another provider" do + File.open(metadata_url.path, "w") do |f| + f.write(<<-RAW) { "name": "foo/bar", "versions": [ @@ -172,16 +206,17 @@ describe Vagrant::Action::Builtin::BoxCheckOutdated do } ] } - RAW + RAW + end + + box = Vagrant::Box.new( + "foo", :virtualbox, "1.0", box_dir, metadata_url: metadata_url.path) + machine.stub(box: box) + + subject.call(env) + + expect(env[:box_outdated]).to be_false end - - box = Vagrant::Box.new( - "foo", :virtualbox, "1.0", box_dir, metadata_url: metadata_url.path) - machine.stub(box: box) - - subject.call(env) - - expect(env[:box_outdated]).to be_false end end end