diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 1f15b6c62..46899197c 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -740,21 +740,34 @@ module Vagrant end end + # This keeps track of the old plugins that need to be reinstalled + # because they were installed with an old version of Ruby. + reinstall = [] + # Load the plugins plugins_json_file = @home_path.join("plugins.json") @logger.debug("Loading plugins from: #{plugins_json_file}") - if plugins_json_file.file? - data = JSON.parse(plugins_json_file.read) - data["installed"].each do |plugin| - @logger.info("Loading plugin from JSON: #{plugin}") - begin - Vagrant.require_plugin(plugin) - rescue Errors::PluginLoadError => e - @ui.error(e.message + "\n") - rescue Errors::PluginLoadFailed => e - @ui.error(e.message + "\n") - end + state = VagrantPlugins::CommandPlugin::StateFile.new(plugins_json_file) + state.installed_plugins.each do |name, extra| + # If the Ruby version changed, then they need to reinstall the plugin + if extra["ruby_version"] != RUBY_VERSION + reinstall << name + next end + + @logger.info("Loading plugin from JSON: #{plugin}") + begin + Vagrant.require_plugin(plugin) + rescue Errors::PluginLoadError => e + @ui.error(e.message + "\n") + rescue Errors::PluginLoadFailed => e + @ui.error(e.message + "\n") + end + end + + if !reinstall.empty? + @ui.warn(I18n.t("vagrant.plugin_needs_reinstall", + names: reinstall.join(", "))) end end diff --git a/plugins/commands/plugin/state_file.rb b/plugins/commands/plugin/state_file.rb index c1543bc8f..6860bdd09 100644 --- a/plugins/commands/plugin/state_file.rb +++ b/plugins/commands/plugin/state_file.rb @@ -24,6 +24,7 @@ module VagrantPlugins def add_plugin(name) if !@data["installed"].has_key?(name) @data["installed"][name] = { + "ruby_version" => RUBY_VERSION, "vagrant_version" => Vagrant::VERSION, } end @@ -65,6 +66,7 @@ module VagrantPlugins new_installed = {} (@data["installed"] || []).each do |plugin| new_installed[plugin] = { + "ruby_version" => "0", "vagrant_version" => "0", } end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index f89789c63..d3cbd88c8 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -42,7 +42,6 @@ en: to automatically delete Chef nodes and clients. chef_run_list_empty: |- Warning: Chef run list is empty. This may not be what you want. - docker_installing: |- Installing Docker (%{version}) onto machine... docker_pulling_images: @@ -56,7 +55,23 @@ en: docker_auto_start_not_available: |- Unable to configure automatic restart of Docker containers on the guest machine + plugin_needs_reinstall: |- + The following plugins were installed with a version of Vagrant + that had different versions of underlying components. Because + these component versions were changed (which rarely happens), + the plugins must be uninstalled and reinstalled. + To ensure that all the dependencies are properly updated as well + it is _highly recommended_ to do a `vagrant plugin uninstall` + prior to reinstalling. + + This message will not go away until all the plugins below are + either uninstalled or uninstalled then reinstalled. + + The plugins below will not be loaded until they're uninstalled + and reinstalled: + + %{names} provisioner_cleanup: |- Running cleanup tasks for '%{name}' provisioner... diff --git a/test/unit/plugins/commands/plugin/state_file_test.rb b/test/unit/plugins/commands/plugin/state_file_test.rb index 4610428b3..a29daa6c5 100644 --- a/test/unit/plugins/commands/plugin/state_file_test.rb +++ b/test/unit/plugins/commands/plugin/state_file_test.rb @@ -29,7 +29,10 @@ describe VagrantPlugins::CommandPlugin::StateFile do instance = described_class.new(path) plugins = instance.installed_plugins expect(plugins.length).to eql(1) - expect(plugins["foo"]).to eql({ "vagrant_version" => Vagrant::VERSION }) + expect(plugins["foo"]).to eql({ + "ruby_version" => RUBY_VERSION, + "vagrant_version" => Vagrant::VERSION, + }) end it "should remove plugins" do @@ -63,6 +66,7 @@ describe VagrantPlugins::CommandPlugin::StateFile do it "should have the right installed plugins" do plugins = subject.installed_plugins expect(plugins.keys).to eql(["foo"]) + expect(plugins["foo"]["ruby_version"]).to eql("0") expect(plugins["foo"]["vagrant_version"]).to eql("0") end end