Seth Vargo 5a4f345363
Use Util::Tempfile when configuring networks
This fixes a fairly large tempfile leak. Vagrant uses a template
renderer to write network configuration files locally to disk. Then,
that temporarily file is uploaded to the remote host and moved into
place. Since Vagrant is such a short-lived process, GC never came along
and cleaned up those tempfiles, resulting in many temporary files being
created through regular Vagrant usage.

The Util::Tempfile class uses a block to ensure the temporary file is
deleted when the block finishes. This API required small tweaks to the
usage, but provides more safety to ensure the files are deleted.
2016-05-28 23:22:34 -04:00

71 lines
2.2 KiB
Ruby

require "digest/md5"
require_relative "base"
require_relative "../../../../lib/vagrant/util/tempfile"
module VagrantPlugins
module Chef
module Provisioner
class ChefApply < Base
def provision
install_chef
verify_binary(chef_binary_path("chef-apply"))
command = "chef-apply"
command << " \"#{target_recipe_path}\""
command << " --log_level #{config.log_level}"
user = @machine.ssh_info[:username]
# Reset upload path permissions for the current ssh user
if windows?
@machine.communicate.sudo("mkdir ""#{config.upload_path}"" -f")
else
@machine.communicate.sudo("mkdir -p #{config.upload_path}")
@machine.communicate.sudo("chown -R #{user} #{config.upload_path}")
end
# Upload the recipe
upload_recipe
@machine.ui.info(I18n.t("vagrant.provisioners.chef.running_apply",
script: config.path)
)
# Execute it with sudo
@machine.communicate.sudo(command) do |type, data|
if [:stderr, :stdout].include?(type)
# Output the data with the proper color based on the stream.
color = (type == :stdout) ? :green : :red
# Chomp the data to avoid the newlines that the Chef outputs
@machine.env.ui.info(data.chomp, color: color, prefix: false)
end
end
end
# The destination (on the guest) where the recipe will live
# @return [String]
def target_recipe_path
key = Digest::MD5.hexdigest(config.recipe)
File.join(config.upload_path, "recipe-#{key}.rb")
end
# Write the raw recipe contents to a tempfile and upload that to the
# machine.
def upload_recipe
# Write the raw recipe contents to a tempfile and upload
Tempfile.create(["chef-apply", ".rb"]) do |f|
f.write(config.recipe)
f.fsync
f.close
# Upload the tempfile to the guest
@machine.communicate.upload(f.path, target_recipe_path)
end
end
end
end
end
end