From df069deac01775cd8f1ccc5a38309d7ebe64986b Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Tue, 4 Apr 2017 17:53:04 -0700 Subject: [PATCH 1/2] Validate plugin sources and report errors if detected. --- lib/vagrant/bundler.rb | 32 +++++++++++++++++-- lib/vagrant/errors.rb | 4 +++ .../plugin/command/mixin_install_opts.rb | 5 +-- plugins/commands/plugin/gem_helper.rb | 6 +++- templates/locales/en.yml | 12 ++++++- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/lib/vagrant/bundler.rb b/lib/vagrant/bundler.rb index 8f3d7aceb..4d43501b0 100644 --- a/lib/vagrant/bundler.rb +++ b/lib/vagrant/bundler.rb @@ -19,13 +19,15 @@ module Vagrant # all Vagrant-installed plugins. class Bundler + # Location of HashiCorp gem repository + HASHICORP_GEMSTORE = "https://gems.hashicorp.com/".freeze + + # Default gem repositories DEFAULT_GEM_SOURCES = [ "https://rubygems.org/".freeze, - "https://gems.hashicorp.com/".freeze + HASHICORP_GEMSTORE ].freeze - HASHICORP_GEMSTORE = "https://gems.hashicorp.com/".freeze - def self.instance @bundler ||= self.new end @@ -262,6 +264,9 @@ module Vagrant @logger.debug("Adding source - #{src}") Gem.sources << src end + + validate_configured_sources! + source_list.values.each{|srcs| srcs.delete_if{|src| default_sources.include?(src)}} installer_set.prefer_sources = source_list @@ -321,6 +326,27 @@ module Vagrant list.values end + # Iterates each configured RubyGem source to validate that it is properly + # available. If source is unavailable an exception is raised. + def validate_configured_sources! + Gem.sources.each_source do |src| + begin + src.load_specs(:released) + rescue Gem::Exception => source_error + if ENV["VAGRANT_ALLOW_PLUGIN_SOURCE_ERRORS"] + @logger.warn("Failed to load configured plugin source: #{src}!") + @logger.warn("Error received attempting to load source (#{src}): #{source_error}") + @logger.warn("Ignoring plugin source load failure due user request via env variable") + else + @logger.error("Failed to load configured plugin source `#{src}`: #{source_error}") + raise Vagrant::Errors::PluginSourceError, + source: src.uri.to_s, + error_msg: source_error.message + end + end + end + end + # Generate the builtin resolver set def generate_builtin_set builtin_set = BuiltinSet.new diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 7778d30ca..fbcad904f 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -596,6 +596,10 @@ module Vagrant error_key(:plugin_init_error) end + class PluginSourceError < VagrantError + error_key(:plugin_source_error) + end + class PushesNotDefined < VagrantError error_key(:pushes_not_defined) end diff --git a/plugins/commands/plugin/command/mixin_install_opts.rb b/plugins/commands/plugin/command/mixin_install_opts.rb index 517b5158b..74e610be1 100644 --- a/plugins/commands/plugin/command/mixin_install_opts.rb +++ b/plugins/commands/plugin/command/mixin_install_opts.rb @@ -3,10 +3,7 @@ module VagrantPlugins module Command module MixinInstallOpts def build_install_opts(o, options) - options[:plugin_sources] = [ - "https://rubygems.org", - "https://gems.hashicorp.com", - ] + options[:plugin_sources] = Vagrant::Bundler::DEFAULT_GEM_SOURCES.dup o.on("--entry-point NAME", String, "The name of the entry point file for loading the plugin.") do |entry_point| diff --git a/plugins/commands/plugin/gem_helper.rb b/plugins/commands/plugin/gem_helper.rb index c9a3dd4ed..1558b859e 100644 --- a/plugins/commands/plugin/gem_helper.rb +++ b/plugins/commands/plugin/gem_helper.rb @@ -43,7 +43,11 @@ module VagrantPlugins # Clear the sources so that installation uses custom sources old_sources = Gem.sources Gem.sources = Gem.default_sources - Gem.sources << "https://gems.hashicorp.com" + Vagrant::Bundler::DEFAULT_GEM_SOURCES.each do |source| + if !Gem.sources.include?(source) + Gem.sources << source + end + end # Use a silent UI so that we have no output Gem::DefaultUserInteraction.use_ui(Gem::SilentUI.new) do diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 8b2a8f67a..aac75731f 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1020,6 +1020,16 @@ en: You can however, install a plugin with the same name to replace these plugins. User-installed plugins take priority over system-installed plugins. + plugin_source_error: |- + Vagrant failed to load a configured plugin source. This can be caused + by a variety of issues including: transient connectivity issues, proxy + filtering rejecting access to a configured plugin source, or a configured + plugin source not responding correctly. Please review the error message + below to help resolve the issue: + + %{error_msg} + + Source: %{source} pushes_not_defined: |- The Vagrantfile does not define any 'push' strategies. In order to use `vagrant push`, you must define at least one push strategy: @@ -1985,7 +1995,7 @@ en: untar_failure: |- The box failed to unpackage properly. Please verify that the box file you're trying to add is not corrupted and that enough disk space - is available and then try again. + is available and then try again. The output from attempting to unpackage (if any): %{output} From 3c8b2ae097965fca3d4ccf56c9407967afb91ffd Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 5 Apr 2017 13:17:48 -0700 Subject: [PATCH 2/2] Include documentation entry for plugin source errors environment variable --- .../docs/other/environmental-variables.html.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/website/source/docs/other/environmental-variables.html.md b/website/source/docs/other/environmental-variables.html.md index 0f827267d..16a308441 100644 --- a/website/source/docs/other/environmental-variables.html.md +++ b/website/source/docs/other/environmental-variables.html.md @@ -66,7 +66,14 @@ a scripting environment in order to set the directory that Vagrant sees. ## `VAGRANT_DOTFILE_PATH` -`VAGRANT_DOTFILE_PATH` can be set to change the directory where Vagrant stores VM-specific state, such as the VirtualBox VM UUID. By default, this is set to `.vagrant`. If you keep your Vagrantfile in a Dropbox folder in order to share the folder between your desktop and laptop (for example), Vagrant will overwrite the files in this directory with the details of the VM on the most recently-used host. To avoid this, you could set `VAGRANT_DOTFILE_PATH` to `.vagrant-laptop` and `.vagrant-desktop` on the respective machines. (Remember to update your `.gitignore`!) +`VAGRANT_DOTFILE_PATH` can be set to change the directory where Vagrant stores +VM-specific state, such as the VirtualBox VM UUID. By default, this is set to +`.vagrant`. If you keep your Vagrantfile in a Dropbox folder in order to share +the folder between your desktop and laptop (for example), Vagrant will overwrite +the files in this directory with the details of the VM on the most recently-used +host. To avoid this, you could set `VAGRANT_DOTFILE_PATH` to `.vagrant-laptop` +and `.vagrant-desktop` on the respective machines. (Remember to update your +`.gitignore`!) ## `VAGRANT_HOME` @@ -128,6 +135,15 @@ Note that any `vagrant plugin` commands automatically do not load any plugins, so if you do install any unstable plugins, you can always use the `vagrant plugin` commands without having to worry. +## `VAGRANT_ALLOW_PLUGIN_SOURCE_ERRORS` + +If this is set to any value, then Vagrant will not error when a configured +plugin source is unavailable. When installing a Vagrant plugin Vagrant +will error and halt if a plugin source is inaccessible. In some cases it +may be desirable to ignore inaccessible sources and continue with the +plugin installation. Enabling this value will cause Vagrant to simply log +the plugin source error and continue. + ## `VAGRANT_NO_PARALLEL` If this is set, Vagrant will not perform any parallel operations (such as