From 5a4f3453631621f982cab78ce0a47ebfe70ef7fa Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Sat, 28 May 2016 23:17:40 -0400 Subject: [PATCH] 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. --- plugins/communicators/winrm/communicator.rb | 17 +++---- plugins/guests/arch/cap/configure_networks.rb | 29 ++++++----- .../guests/coreos/cap/configure_networks.rb | 15 +++--- .../guests/debian/cap/configure_networks.rb | 22 ++++---- .../guests/fedora/cap/configure_networks.rb | 18 +++---- .../guests/freebsd/cap/configure_networks.rb | 17 +++---- .../guests/funtoo/cap/configure_networks.rb | 18 ++++--- .../guests/gentoo/cap/configure_networks.rb | 17 +++---- .../guests/netbsd/cap/configure_networks.rb | 18 +++---- plugins/guests/nixos/cap/change_host_name.rb | 19 +++---- .../guests/nixos/cap/configure_networks.rb | 20 ++++---- .../guests/openbsd/cap/configure_networks.rb | 16 +++--- .../guests/redhat/cap/configure_networks.rb | 18 +++---- .../slackware/cap/configure_networks.rb | 18 +++---- plugins/guests/suse/cap/configure_networks.rb | 18 +++---- .../provisioners/ansible/provisioner/guest.rb | 18 +++---- .../chef/provisioner/chef_apply.rb | 20 ++++---- .../guests/arch/cap/change_host_name_test.rb | 37 ++++++++++++++ .../arch/cap/configure_networks_test.rb | 48 ++++++++++++++++++ .../coreos/cap/change_host_name_test.rb | 37 ++++++++++++++ .../debian/cap/change_host_name_test.rb | 10 ++-- .../debian/cap/configure_networks_test.rb | 50 +++++++++++++++++++ 22 files changed, 339 insertions(+), 161 deletions(-) create mode 100644 test/unit/plugins/guests/arch/cap/change_host_name_test.rb create mode 100644 test/unit/plugins/guests/arch/cap/configure_networks_test.rb create mode 100644 test/unit/plugins/guests/coreos/cap/change_host_name_test.rb create mode 100644 test/unit/plugins/guests/debian/cap/configure_networks_test.rb diff --git a/plugins/communicators/winrm/communicator.rb b/plugins/communicators/winrm/communicator.rb index fe884d272..bb04ee277 100644 --- a/plugins/communicators/winrm/communicator.rb +++ b/plugins/communicators/winrm/communicator.rb @@ -5,11 +5,14 @@ require "log4r" require_relative "helper" require_relative "shell" require_relative "command_filter" +require_relative "../../../lib/vagrant/util/tempfile" module VagrantPlugins module CommunicatorWinRM # Provides communication channel for Vagrant commands via WinRM. class Communicator < Vagrant.plugin("2", :communicator) + include Vagrant::Util + def self.match?(machine) # This is useless, and will likely be removed in the future (this # whole method). @@ -202,15 +205,11 @@ module VagrantPlugins interactive: interactive, }) guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1" - file = Tempfile.new(["vagrant-elevated-shell", "ps1"]) - begin - file.write(script) - file.fsync - file.close - upload(file.path, guest_script_path) - ensure - file.close - file.unlink + Tempfile.create(["vagrant-elevated-shell", "ps1"]) do |f| + f.write(script) + f.fsync + f.close + upload(f.path, guest_script_path) end # Convert to double byte unicode string then base64 encode diff --git a/plugins/guests/arch/cap/configure_networks.rb b/plugins/guests/arch/cap/configure_networks.rb index ad5a356d3..76de628dd 100644 --- a/plugins/guests/arch/cap/configure_networks.rb +++ b/plugins/guests/arch/cap/configure_networks.rb @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestArch @@ -10,23 +9,29 @@ module VagrantPlugins include Vagrant::Util def self.configure_networks(machine, networks) - interfaces = Array.new + tempfiles = [] + interfaces = [] + machine.communicate.sudo("ip -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'") do |_, result| interfaces = result.split("\n") end - networks.each do |network| + networks.each.with_index do |network, i| network[:device] = interfaces[network[:interface]] - entry = TemplateRenderer.render("guests/arch/network_#{network[:type]}", options: network) + entry = TemplateRenderer.render("guests/arch/network_#{network[:type]}", + options: network) - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close + remote_path = "/tmp/vagrant-network-#{Time.now.to_i}-#{i}" - machine.communicate.upload(temp.path, "/tmp/vagrant_network") - machine.communicate.sudo("mv /tmp/vagrant_network /etc/netctl/#{network[:device]}") + Tempfile.create("arch-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, remote_path) + end + + machine.communicate.sudo("mv #{remote_path} /etc/netctl/#{network[:device]}") machine.communicate.sudo("ip link set #{network[:device]} down && netctl restart #{network[:device]} && netctl enable #{network[:device]}") end end diff --git a/plugins/guests/coreos/cap/configure_networks.rb b/plugins/guests/coreos/cap/configure_networks.rb index 819f6f818..eeca1302c 100644 --- a/plugins/guests/coreos/cap/configure_networks.rb +++ b/plugins/guests/coreos/cap/configure_networks.rb @@ -1,6 +1,5 @@ -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestCoreOS @@ -54,11 +53,11 @@ module VagrantPlugins }) end - Tempfile.open("vagrant") do |temp| - temp.binmode - temp.write(entry) - temp.close - comm.upload(temp.path, "/tmp/etcd-cluster.service") + Tempfile.create("coreos-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + comm.upload(f.path, "/tmp/etcd-cluster.service") end comm.sudo("mv /tmp/etcd-cluster.service /media/state/units/") diff --git a/plugins/guests/debian/cap/configure_networks.rb b/plugins/guests/debian/cap/configure_networks.rb index 0580bc293..15095968e 100644 --- a/plugins/guests/debian/cap/configure_networks.rb +++ b/plugins/guests/debian/cap/configure_networks.rb @@ -1,7 +1,7 @@ -require 'set' -require 'tempfile' +require "set" -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestDebian @@ -29,14 +29,14 @@ module VagrantPlugins entries << entry end - # Perform the careful dance necessary to reconfigure - # the network interfaces - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entries.join("\n")) - temp.close - - comm.upload(temp.path, "/tmp/vagrant-network-entry") + # Perform the careful dance necessary to reconfigure the network + # interfaces. + Tempfile.create("debian-configure-networks") do |f| + f.write(entries.join("\n")) + f.fsync + f.close + comm.upload(f.path, "/tmp/vagrant-network-entry") + end # Bring down all the interfaces we're reconfiguring. By bringing down # each specifically, we avoid reconfiguring eth0 (the NAT interface) so diff --git a/plugins/guests/fedora/cap/configure_networks.rb b/plugins/guests/fedora/cap/configure_networks.rb index d2aa8beca..425d4c5db 100644 --- a/plugins/guests/fedora/cap/configure_networks.rb +++ b/plugins/guests/fedora/cap/configure_networks.rb @@ -1,8 +1,8 @@ require "set" -require "tempfile" -require "vagrant/util/retryable" -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/retryable" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestFedora @@ -96,12 +96,12 @@ module VagrantPlugins entry = TemplateRenderer.render("guests/fedora/network_#{network[:type]}", options: network) - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close - - machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry_#{interface}") + Tempfile.create("fedora-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, "/tmp/vagrant-network-entry_#{interface}") + end end # Bring down all the interfaces we're reconfiguring. By bringing down diff --git a/plugins/guests/freebsd/cap/configure_networks.rb b/plugins/guests/freebsd/cap/configure_networks.rb index 27dfc850d..4744c641d 100644 --- a/plugins/guests/freebsd/cap/configure_networks.rb +++ b/plugins/guests/freebsd/cap/configure_networks.rb @@ -1,6 +1,5 @@ -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestFreeBSD @@ -29,13 +28,13 @@ module VagrantPlugins entry = TemplateRenderer.render("guests/freebsd/network_#{network[:type]}", options: network, ifname: ifname) - # Write the entry to a temporary location - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close + Tempfile.create("freebsd-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, "/tmp/vagrant-network-entry") + end - machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry") machine.communicate.sudo("su -m root -c 'cat /tmp/vagrant-network-entry >> /etc/rc.conf'", {shell: "sh"}) machine.communicate.sudo("rm -f /tmp/vagrant-network-entry", {shell: "sh"}) diff --git a/plugins/guests/funtoo/cap/configure_networks.rb b/plugins/guests/funtoo/cap/configure_networks.rb index c52182b6f..d5a1a653a 100644 --- a/plugins/guests/funtoo/cap/configure_networks.rb +++ b/plugins/guests/funtoo/cap/configure_networks.rb @@ -1,6 +1,5 @@ -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestFuntoo @@ -23,12 +22,15 @@ module VagrantPlugins ifFile = "netif.eth#{network[:interface]}" entry = TemplateRenderer.render("guests/funtoo/network_#{network[:type]}", options: network) + # Upload the entry to a temporary location - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close - comm.upload(temp.path, "/tmp/vagrant-#{ifFile}") + Tempfile.create("funtoo-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + comm.upload(f.path, "/tmp/vagrant-#{ifFile}") + end + comm.sudo("cp /tmp/vagrant-#{ifFile} /etc/conf.d/#{ifFile}") comm.sudo("chmod 0644 /etc/conf.d/#{ifFile}") comm.sudo("ln -fs /etc/init.d/netif.tmpl /etc/init.d/#{ifFile}") diff --git a/plugins/guests/gentoo/cap/configure_networks.rb b/plugins/guests/gentoo/cap/configure_networks.rb index 549977b02..5d7796ef0 100644 --- a/plugins/guests/gentoo/cap/configure_networks.rb +++ b/plugins/guests/gentoo/cap/configure_networks.rb @@ -1,6 +1,5 @@ -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestGentoo @@ -21,12 +20,12 @@ module VagrantPlugins options: network) # Upload the entry to a temporary location - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close - - comm.upload(temp.path, "/tmp/vagrant-network-entry") + Tempfile.create("gentoo-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + comm.upload(f.path, "/tmp/vagrant-network-entry") + end # Configure the interface comm.sudo("ln -fs /etc/init.d/net.lo /etc/init.d/net.eth#{network[:interface]}") diff --git a/plugins/guests/netbsd/cap/configure_networks.rb b/plugins/guests/netbsd/cap/configure_networks.rb index b5c157c4c..d52f48267 100644 --- a/plugins/guests/netbsd/cap/configure_networks.rb +++ b/plugins/guests/netbsd/cap/configure_networks.rb @@ -1,6 +1,5 @@ -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestNetBSD @@ -20,13 +19,13 @@ module VagrantPlugins entry = TemplateRenderer.render("guests/netbsd/network_#{network[:type]}", options: network) - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close + Tempfile.create("netbsd-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, "/tmp/vagrant-network-entry") + end - # upload it and append it to the new rc.conf file - machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry") machine.communicate.sudo("cat /tmp/vagrant-network-entry >> #{newrcconf}") machine.communicate.sudo("rm -f /tmp/vagrant-network-entry") @@ -45,7 +44,6 @@ module VagrantPlugins # install new rc.conf machine.communicate.sudo("install -c -o 0 -g 0 -m 644 #{newrcconf} /etc/rc.conf") - end end end diff --git a/plugins/guests/nixos/cap/change_host_name.rb b/plugins/guests/nixos/cap/change_host_name.rb index 6b951113b..5fbd5c38a 100644 --- a/plugins/guests/nixos/cap/change_host_name.rb +++ b/plugins/guests/nixos/cap/change_host_name.rb @@ -1,6 +1,5 @@ -require 'tempfile' - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestNixos @@ -16,13 +15,15 @@ module VagrantPlugins # Upload a file. def self.upload(machine, content, remote_path) - local_temp = Tempfile.new("vagrant-upload") - local_temp.binmode - local_temp.write(content) - local_temp.close remote_temp = mktemp(machine) - machine.communicate.upload(local_temp.path, "#{remote_temp}") - local_temp.delete + + Tempfile.create("nixos-change-host-name") do |f| + f.write(content) + f.fsync + f.close + machine.communicate.upload(f.path, "#{remote_temp}") + end + machine.communicate.sudo("mv #{remote_temp} #{remote_path}") end diff --git a/plugins/guests/nixos/cap/configure_networks.rb b/plugins/guests/nixos/cap/configure_networks.rb index b2174c81c..4161610b4 100644 --- a/plugins/guests/nixos/cap/configure_networks.rb +++ b/plugins/guests/nixos/cap/configure_networks.rb @@ -1,7 +1,7 @@ -require 'tempfile' -require 'ipaddr' +require "ipaddr" -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestNixos @@ -65,13 +65,15 @@ module VagrantPlugins # Upload a file. def self.upload(machine, content, remote_path) - local_temp = Tempfile.new("vagrant-upload") - local_temp.binmode - local_temp.write(content) - local_temp.close remote_temp = mktemp(machine) - machine.communicate.upload(local_temp.path, "#{remote_temp}") - local_temp.delete + + Tempfile.create("nixos-configure-networks") do |f| + f.write(content) + f.fsync + f.close + machine.communicate.upload(f.path, "#{remote_temp}") + end + machine.communicate.sudo("mv #{remote_temp} #{remote_path}") end diff --git a/plugins/guests/openbsd/cap/configure_networks.rb b/plugins/guests/openbsd/cap/configure_networks.rb index 5ca9fed07..774fe2c79 100644 --- a/plugins/guests/openbsd/cap/configure_networks.rb +++ b/plugins/guests/openbsd/cap/configure_networks.rb @@ -1,6 +1,5 @@ -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestOpenBSD @@ -13,10 +12,12 @@ module VagrantPlugins entry = TemplateRenderer.render("guests/openbsd/network_#{network[:type]}", options: network) - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close + Tempfile.create("openbsd-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, "/tmp/vagrant-network-entry") + end # Determine the interface prefix... command = "ifconfig -a | grep -o ^[0-9a-z]*" @@ -31,7 +32,6 @@ module VagrantPlugins end end - machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry") machine.communicate.sudo("mv /tmp/vagrant-network-entry /etc/hostname.#{ifname}") # remove old configurations diff --git a/plugins/guests/redhat/cap/configure_networks.rb b/plugins/guests/redhat/cap/configure_networks.rb index f176cca3d..7001bacc8 100644 --- a/plugins/guests/redhat/cap/configure_networks.rb +++ b/plugins/guests/redhat/cap/configure_networks.rb @@ -1,8 +1,8 @@ require "set" -require "tempfile" -require "vagrant/util/retryable" -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/retryable" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestRedHat @@ -55,12 +55,12 @@ module VagrantPlugins entry = TemplateRenderer.render("guests/redhat/network_#{network[:type]}", options: network) - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close - - machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry_#{network[:interface]}") + Tempfile.create("red-hat-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, "/tmp/vagrant-network-entry_#{network[:interface]}") + end end # Bring down all the interfaces we're reconfiguring. By bringing down diff --git a/plugins/guests/slackware/cap/configure_networks.rb b/plugins/guests/slackware/cap/configure_networks.rb index dc84080e0..d3b8e23fc 100644 --- a/plugins/guests/slackware/cap/configure_networks.rb +++ b/plugins/guests/slackware/cap/configure_networks.rb @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -require "tempfile" - -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestSlackware @@ -20,15 +19,16 @@ module VagrantPlugins entry = TemplateRenderer.render("guests/slackware/network_#{network[:type]}", options: network) - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close + Tempfile.create("slackware-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, "/tmp/vagrant_network") + end - machine.communicate.upload(temp.path, "/tmp/vagrant_network") machine.communicate.sudo("mv /tmp/vagrant_network /etc/rc.d/rc.inet1.conf") machine.communicate.sudo("/etc/rc.d/rc.inet1") - end + end end end end diff --git a/plugins/guests/suse/cap/configure_networks.rb b/plugins/guests/suse/cap/configure_networks.rb index 00902dbd0..204ff5f69 100644 --- a/plugins/guests/suse/cap/configure_networks.rb +++ b/plugins/guests/suse/cap/configure_networks.rb @@ -1,8 +1,8 @@ require "set" -require "tempfile" -require "vagrant/util/retryable" -require "vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/retryable" +require_relative "../../../../lib/vagrant/util/template_renderer" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module GuestSUSE @@ -33,12 +33,12 @@ module VagrantPlugins entry = TemplateRenderer.render("guests/suse/network_#{network[:type]}", options: network) - temp = Tempfile.new("vagrant") - temp.binmode - temp.write(entry) - temp.close - - machine.communicate.upload(temp.path, "/tmp/vagrant-network-entry_#{network[:interface]}") + Tempfile.create("suse-configure-networks") do |f| + f.write(entry) + f.fsync + f.close + machine.communicate.upload(f.path, "/tmp/vagrant-network-entry_#{network[:interface]}") + end end # Bring down all the interfaces we're reconfiguring. By bringing down diff --git a/plugins/provisioners/ansible/provisioner/guest.rb b/plugins/provisioners/ansible/provisioner/guest.rb index ade03151e..3f9fd7163 100644 --- a/plugins/provisioners/ansible/provisioner/guest.rb +++ b/plugins/provisioners/ansible/provisioner/guest.rb @@ -1,11 +1,11 @@ -require 'tempfile' - require_relative "base" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module Ansible module Provisioner class Guest < Base + include Vagrant::Util def initialize(machine, config) super @@ -103,14 +103,14 @@ module VagrantPlugins inventory_basedir = File.join(config.tmp_path, "inventory") inventory_path = File.join(inventory_basedir, "vagrant_ansible_local_inventory") - temp_inventory = Tempfile.new("vagrant_ansible_local_inventory_#{@machine.name}") - temp_inventory.write(inventory_content) - temp_inventory.close - create_and_chown_remote_folder(inventory_basedir) - @machine.communicate.tap do |comm| - comm.sudo("rm -f #{inventory_path}", error_check: false) - comm.upload(temp_inventory.path, inventory_path) + @machine.communicate.sudo("rm -f #{inventory_path}", error_check: false) + + Tempfile.create("ansible-local-inventory-#{@machine.name}") do |f| + f.write(inventory_content) + f.fsync + f.close + @machine.communicate.upload(f.path, inventory_path) end return inventory_basedir diff --git a/plugins/provisioners/chef/provisioner/chef_apply.rb b/plugins/provisioners/chef/provisioner/chef_apply.rb index 602c81f3d..a5aab3d8a 100644 --- a/plugins/provisioners/chef/provisioner/chef_apply.rb +++ b/plugins/provisioners/chef/provisioner/chef_apply.rb @@ -1,7 +1,7 @@ require "digest/md5" -require "tempfile" require_relative "base" +require_relative "../../../../lib/vagrant/util/tempfile" module VagrantPlugins module Chef @@ -54,17 +54,15 @@ module VagrantPlugins # 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 - file = Tempfile.new(["vagrant-chef-apply", ".rb"]) - file.write(config.recipe) - file.rewind + # 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(file.path, target_recipe_path) - ensure - # Delete our template - file.close - file.unlink + # Upload the tempfile to the guest + @machine.communicate.upload(f.path, target_recipe_path) + end end end end diff --git a/test/unit/plugins/guests/arch/cap/change_host_name_test.rb b/test/unit/plugins/guests/arch/cap/change_host_name_test.rb new file mode 100644 index 000000000..c8cf9c1ce --- /dev/null +++ b/test/unit/plugins/guests/arch/cap/change_host_name_test.rb @@ -0,0 +1,37 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestArch::Cap::ChangeHostName" do + let(:described_class) do + VagrantPlugins::GuestArch::Plugin + .components + .guest_capabilities[:arch] + .get(:change_host_name) + end + + let(:machine) { double("machine") } + let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(communicator) + end + + after do + communicator.verify_expectations! + end + + describe ".change_host_name" do + let(:hostname) { "example.com" } + + it "sets the hostname" do + communicator.stub_command("sudo hostname | grep '#{hostname}'", exit_code: 1) + communicator.expect_command("hostnamectl set-hostname #{hostname}") + described_class.change_host_name(machine, hostname) + end + + it "does not change the hostname if already set" do + communicator.stub_command("sudo hostname | grep '#{hostname}'", exit_code: 0) + described_class.change_host_name(machine, hostname) + expect(communicator.received_commands.size).to eq(1) + end + end +end diff --git a/test/unit/plugins/guests/arch/cap/configure_networks_test.rb b/test/unit/plugins/guests/arch/cap/configure_networks_test.rb new file mode 100644 index 000000000..2f6de689e --- /dev/null +++ b/test/unit/plugins/guests/arch/cap/configure_networks_test.rb @@ -0,0 +1,48 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestArch::Cap::ConfigureNetworks" do + let(:described_class) do + VagrantPlugins::GuestArch::Plugin + .components + .guest_capabilities[:arch] + .get(:configure_networks) + end + + let(:machine) { double("machine") } + let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(communicator) + communicator.stub_command("ip -o -0 addr | grep -v LOOPBACK | awk '{print $2}' | sed 's/://'", + stdout: "eth1\neth2") + end + + after do + communicator.verify_expectations! + end + + describe ".configure_networks" do + let(:network_1) do + { + interface: 0, + type: "dhcp", + } + end + + let(:network_2) do + { + interface: 1, + type: "static", + ip: "33.33.33.10", + netmask: "255.255.0.0", + gateway: "33.33.0.1", + } + end + + it "creates and starts the networks" do + communicator.expect_command("ip link set eth1 down && netctl restart eth1 && netctl enable eth1") + communicator.expect_command("ip link set eth2 down && netctl restart eth2 && netctl enable eth2") + described_class.configure_networks(machine, [network_1, network_2]) + end + end +end diff --git a/test/unit/plugins/guests/coreos/cap/change_host_name_test.rb b/test/unit/plugins/guests/coreos/cap/change_host_name_test.rb new file mode 100644 index 000000000..d893384ab --- /dev/null +++ b/test/unit/plugins/guests/coreos/cap/change_host_name_test.rb @@ -0,0 +1,37 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestCoreOS::Cap::ChangeHostName" do + let(:described_class) do + VagrantPlugins::GuestCoreOS::Plugin + .components + .guest_capabilities[:coreos] + .get(:change_host_name) + end + + let(:machine) { double("machine") } + let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(communicator) + end + + after do + communicator.verify_expectations! + end + + describe ".change_host_name" do + let(:hostname) { "example.com" } + + it "sets the hostname" do + communicator.stub_command("sudo hostname --fqdn | grep '#{hostname}'", exit_code: 1) + communicator.expect_command("hostname example") + described_class.change_host_name(machine, hostname) + end + + it "does not change the hostname if already set" do + communicator.stub_command("sudo hostname --fqdn | grep '#{hostname}'", exit_code: 0) + described_class.change_host_name(machine, hostname) + expect(communicator.received_commands.size).to eq(1) + end + end +end diff --git a/test/unit/plugins/guests/debian/cap/change_host_name_test.rb b/test/unit/plugins/guests/debian/cap/change_host_name_test.rb index 76a1a48ba..ce18667ef 100644 --- a/test/unit/plugins/guests/debian/cap/change_host_name_test.rb +++ b/test/unit/plugins/guests/debian/cap/change_host_name_test.rb @@ -1,10 +1,14 @@ -require File.expand_path("../../../../../base", __FILE__) -require File.expand_path("../../../support/shared/debian_like_host_name_examples", __FILE__) +require_relative "../../../../base" +require_relative "../../support/shared/debian_like_host_name_examples" describe "VagrantPlugins::GuestDebian::Cap::ChangeHostName" do let(:described_class) do - VagrantPlugins::GuestDebian::Plugin.components.guest_capabilities[:debian].get(:change_host_name) + VagrantPlugins::GuestDebian::Plugin + .components + .guest_capabilities[:debian] + .get(:change_host_name) end + let(:machine) { double("machine") } let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } let(:old_hostname) { 'oldhostname.olddomain.tld' } diff --git a/test/unit/plugins/guests/debian/cap/configure_networks_test.rb b/test/unit/plugins/guests/debian/cap/configure_networks_test.rb new file mode 100644 index 000000000..51d717445 --- /dev/null +++ b/test/unit/plugins/guests/debian/cap/configure_networks_test.rb @@ -0,0 +1,50 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::GuestDebian::Cap::ConfigureNetworks" do + let(:described_class) do + VagrantPlugins::GuestDebian::Plugin + .components + .guest_capabilities[:debian] + .get(:configure_networks) + end + + let(:machine) { double("machine") } + let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + + before do + allow(machine).to receive(:communicate).and_return(communicator) + end + + after do + communicator.verify_expectations! + end + + describe ".configure_networks" do + let(:network_0) do + { + interface: 0, + type: "dhcp", + } + end + + let(:network_1) do + { + interface: 1, + type: "static", + ip: "33.33.33.10", + netmask: "255.255.0.0", + gateway: "33.33.0.1", + } + end + + it "creates and starts the networks" do + communicator.expect_command("/sbin/ifdown eth0 2> /dev/null || true") + communicator.expect_command("/sbin/ip addr flush dev eth0 2> /dev/null") + communicator.expect_command("/sbin/ifdown eth1 2> /dev/null || true") + communicator.expect_command("/sbin/ip addr flush dev eth1 2> /dev/null") + communicator.expect_command("/sbin/ifup eth0") + communicator.expect_command("/sbin/ifup eth1") + described_class.configure_networks(machine, [network_0, network_1]) + end + end +end