Merge pull request #7354 from mitchellh/sethvargo/bundler_leak
Fix file leaking in bundler
This commit is contained in:
commit
11ed254708
|
@ -2,6 +2,7 @@ require "monitor"
|
||||||
require "pathname"
|
require "pathname"
|
||||||
require "set"
|
require "set"
|
||||||
require "tempfile"
|
require "tempfile"
|
||||||
|
require "fileutils"
|
||||||
|
|
||||||
require "bundler"
|
require "bundler"
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup the Bundler configuration
|
# Setup the Bundler configuration
|
||||||
@configfile = File.open(Tempfile.new("vagrant").path + "1", "w+")
|
@configfile = tempfile("vagrant-configfile")
|
||||||
@configfile.close
|
@configfile.close
|
||||||
|
|
||||||
# Build up the Gemfile for our Bundler context. We make sure to
|
# Build up the Gemfile for our Bundler context. We make sure to
|
||||||
|
@ -84,9 +85,13 @@ module Vagrant
|
||||||
|
|
||||||
# Removes any temporary files created by init
|
# Removes any temporary files created by init
|
||||||
def deinit
|
def deinit
|
||||||
File.unlink(ENV["BUNDLE_APP_CONFIG"]) rescue nil
|
# If we weren't enabled, then we don't do anything.
|
||||||
File.unlink(ENV["BUNDLE_CONFIG"]) rescue nil
|
return if !@enabled
|
||||||
File.unlink(ENV["GEMFILE"]) rescue nil
|
|
||||||
|
FileUtils.rm_rf(ENV["BUNDLE_APP_CONFIG"]) rescue nil
|
||||||
|
FileUtils.rm_f(ENV["BUNDLE_CONFIG"]) rescue nil
|
||||||
|
FileUtils.rm_f(ENV["BUNDLE_GEMFILE"]) rescue nil
|
||||||
|
FileUtils.rm_f(ENV["BUNDLE_GEMFILE"]+".lock") rescue nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Installs the list of plugins.
|
# Installs the list of plugins.
|
||||||
|
@ -181,7 +186,7 @@ module Vagrant
|
||||||
def build_gemfile(plugins)
|
def build_gemfile(plugins)
|
||||||
sources = plugins.values.map { |p| p["sources"] }.flatten.compact.uniq
|
sources = plugins.values.map { |p| p["sources"] }.flatten.compact.uniq
|
||||||
|
|
||||||
f = File.open(Tempfile.new("vagrant").path + "2", "w+")
|
f = tempfile("vagrant-gemfile")
|
||||||
f.tap do |gemfile|
|
f.tap do |gemfile|
|
||||||
sources.each do |source|
|
sources.each do |source|
|
||||||
next if source == ""
|
next if source == ""
|
||||||
|
@ -203,7 +208,6 @@ module Vagrant
|
||||||
gemfile.puts(%Q[gem "#{name}", #{version.inspect}, #{opts.inspect}])
|
gemfile.puts(%Q[gem "#{name}", #{version.inspect}, #{opts.inspect}])
|
||||||
end
|
end
|
||||||
gemfile.puts("end")
|
gemfile.puts("end")
|
||||||
|
|
||||||
gemfile.close
|
gemfile.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -250,11 +254,14 @@ module Vagrant
|
||||||
def with_isolated_gem
|
def with_isolated_gem
|
||||||
raise Errors::BundlerDisabled if !@enabled
|
raise Errors::BundlerDisabled if !@enabled
|
||||||
|
|
||||||
|
tmp_gemfile = tempfile("vagrant-gemfile")
|
||||||
|
tmp_gemfile.close
|
||||||
|
|
||||||
# Remove bundler settings so that Bundler isn't loaded when building
|
# Remove bundler settings so that Bundler isn't loaded when building
|
||||||
# native extensions because it causes all sorts of problems.
|
# native extensions because it causes all sorts of problems.
|
||||||
old_rubyopt = ENV["RUBYOPT"]
|
old_rubyopt = ENV["RUBYOPT"]
|
||||||
old_gemfile = ENV["BUNDLE_GEMFILE"]
|
old_gemfile = ENV["BUNDLE_GEMFILE"]
|
||||||
ENV["BUNDLE_GEMFILE"] = Tempfile.new("vagrant-gemfile").path
|
ENV["BUNDLE_GEMFILE"] = tmp_gemfile.path
|
||||||
ENV["RUBYOPT"] = (ENV["RUBYOPT"] || "").gsub(/-rbundler\/setup\s*/, "")
|
ENV["RUBYOPT"] = (ENV["RUBYOPT"] || "").gsub(/-rbundler\/setup\s*/, "")
|
||||||
|
|
||||||
# Set the GEM_HOME so gems are installed only to our local gem dir
|
# Set the GEM_HOME so gems are installed only to our local gem dir
|
||||||
|
@ -284,6 +291,8 @@ module Vagrant
|
||||||
return yield
|
return yield
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
|
tmp_gemfile.unlink rescue nil
|
||||||
|
|
||||||
ENV["BUNDLE_GEMFILE"] = old_gemfile
|
ENV["BUNDLE_GEMFILE"] = old_gemfile
|
||||||
ENV["GEM_HOME"] = @gem_home
|
ENV["GEM_HOME"] = @gem_home
|
||||||
ENV["RUBYOPT"] = old_rubyopt
|
ENV["RUBYOPT"] = old_rubyopt
|
||||||
|
@ -293,6 +302,17 @@ module Vagrant
|
||||||
Gem::Specification.all = old_all
|
Gem::Specification.all = old_all
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This method returns a proper "tempfile" on disk. Ruby's Tempfile class
|
||||||
|
# would work really great for this, except GC can come along and remove
|
||||||
|
# the file before we are done with it. This is because we "close" the file,
|
||||||
|
# but we might be shelling out to a subprocess.
|
||||||
|
#
|
||||||
|
# @return [File]
|
||||||
|
def tempfile(name)
|
||||||
|
path = Dir::Tmpname.create(name) {}
|
||||||
|
return File.open(path, "w+")
|
||||||
|
end
|
||||||
|
|
||||||
# This is pretty hacky but it is a custom implementation of
|
# This is pretty hacky but it is a custom implementation of
|
||||||
# Gem::ConfigFile so that we don't load any gemrc files.
|
# Gem::ConfigFile so that we don't load any gemrc files.
|
||||||
class NilGemConfig < Gem::ConfigFile
|
class NilGemConfig < Gem::ConfigFile
|
||||||
|
|
|
@ -55,6 +55,7 @@ module VagrantPlugins
|
||||||
exit_status = env[:ssh_run_exit_status] || 0
|
exit_status = env[:ssh_run_exit_status] || 0
|
||||||
return exit_status
|
return exit_status
|
||||||
else
|
else
|
||||||
|
Vagrant::Bundler.instance.deinit
|
||||||
@logger.debug("Invoking `ssh` action on machine")
|
@logger.debug("Invoking `ssh` action on machine")
|
||||||
vm.action(:ssh, ssh_opts: ssh_opts)
|
vm.action(:ssh, ssh_opts: ssh_opts)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue