diff --git a/lib/vagrant/util.rb b/lib/vagrant/util.rb index db729bfdc..896b5d7e0 100644 --- a/lib/vagrant/util.rb +++ b/lib/vagrant/util.rb @@ -2,6 +2,7 @@ module Vagrant module Util autoload :Busy, 'vagrant/util/busy' autoload :Counter, 'vagrant/util/counter' + autoload :Env, 'vagrant/util/env' autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access' autoload :Platform, 'vagrant/util/platform' autoload :Retryable, 'vagrant/util/retryable' diff --git a/lib/vagrant/util/env.rb b/lib/vagrant/util/env.rb new file mode 100644 index 000000000..e7c23ccc6 --- /dev/null +++ b/lib/vagrant/util/env.rb @@ -0,0 +1,43 @@ +module Vagrant + module Util + class Env + # + # Execute the given command, removing any Ruby-specific environment + # variables. This is an "enhanced" version of `Bundler.with_clean_env`, + # which only removes Bundler-specific values. We need to remove all + # values, specifically: + # + # - _ORIGINAL_GEM_PATH + # - GEM_PATH + # - GEM_HOME + # - GEM_ROOT + # - BUNDLE_BIN_PATH + # - BUNDLE_GEMFILE + # - RUBYLIB + # - RUBYOPT + # - RUBY_ENGINE + # - RUBY_ROOT + # - RUBY_VERSION + # + # This will escape Vagrant's environment entirely, which is required if + # calling an executable that lives in another Ruby environment. The + # original environment restored at the end of this call. + # + # @param [Proc] block + # the block to execute with the cleaned environment + # + def with_clean_env(&block) + original = ENV.to_hash + + ENV.delete('_ORIGINAL_GEM_PATH') + ENV.delete_if { |k,_| k.start_with?('BUNDLE_') } + ENV.delete_if { |k,_| k.start_with?('GEM_') } + ENV.delete_if { |k,_| k.start_with?('RUBY') } + + yield + ensure + ENV.replace(original.to_hash) + end + end + end +end diff --git a/plugins/provisioners/chef/provisioner/chef_client.rb b/plugins/provisioners/chef/provisioner/chef_client.rb index 5824f56be..c9b0ab6c0 100644 --- a/plugins/provisioners/chef/provisioner/chef_client.rb +++ b/plugins/provisioners/chef/provisioner/chef_client.rb @@ -110,7 +110,7 @@ module VagrantPlugins # Knife is not part of the current Vagrant bundle, so it needs to run # in the context of the system. Vagrant.global_lock do - Bundler.with_clean_env do + Vagrant::Util::Env.with_clean_env do command = ["knife", deletable, "delete", "--yes", node_name] r = Vagrant::Util::Subprocess.execute(*command) if r.exit_code != 0